char *getcwd(char *buf, size_t size)
功能:
获取当前工作目录(绝对路径)
参数:
buf 保存工作路径的缓冲区
size 指定buf可以存储字节数
返回值:
成功 buf的起始地址
失败 NULL
#include
#include
#define SIZE 32
int main()
{
char buf[SIZE] = {0};
char* p = getcwd(buf,SIZE);
if(NULL == p)
{
perror("getcwd");
return 1;
}
printf("%s\n",buf);
return 0;
}
int chdir(const char *path);
功能:
改变当前进程工作目录
参数:
path 相对路径或者绝对路径
返回值:
成功 0
失败 -1
#include
#include
#define SIZE 32
int main()
{
char buf[SIZE] = {0};
char* p = getcwd(buf,SIZE);
if(NULL == p)
{
perror("getcwd");
return 1;
}
printf("%s\n",buf);
return 0;
}
itcast@ubuntu:~/classcode/day05$ ^C
itcast@ubuntu:~/classcode/day05$ cat 2chdir.c
#include
#include
#define SIZE 32
#include
int main()
{
char *p = NULL;
char buf[SIZE];
memset(buf, 0, SIZE);
//获取当前进程工作路径
p = getcwd(buf, SIZE);
if (NULL == p)
{
perror("getcwd");
return 1;
}
printf("buf: %s\n", buf);
int ret = chdir("/home/itcast");
if(ret == -1)
{
perror("chdir");
return 1;
}
p = getcwd(buf, SIZE);
if (NULL == p)
{
perror("getcwd");
return 1;
}
printf("buf: %s\n", buf);
return 0;
}
DIR *opendir(const char *name);
功能:
打开目录
参数:
name: 目录绝对路径或者相对路径
返回值:
成功 DIR指针类型
失败 NULL
int closedir(DIR *dirp);
功能:
关闭目录
参数:
dirp opendir函数的返回值
返回值:
成功 0
失败 -1
#include
#include
#include
int main()
{
DIR * d = NULL;
d = opendir("/home/itcast");
if(NULL == d)
{
perror("opendir");
return 1;
}
printf("打开目录成功\n");
closedir(d);
printf("关闭目录成功\n");
return 0;
}
struct dirent *readdir(DIR *dirp)
功能:
读目录
参数:
dirp opendir函数的返回值
返回值:
成功: 结构体指针
失败: NULL
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
d_type 文件的类型
d_name 文件名
#include
#include
#include
int main()
{
DIR *dir = NULL;
struct dirent* d;
//打开目录
dir = opendir("/home/itcast");
if (NULL == dir)
{
printf("opendir failed...\n");
return 1;
}
while(1)
{
d = readdir(dir);
if(d == NULL)
break;
printf("type: %u, name:%s\n",d->d_type,d->d_name);
}
closedir(dir);
return 0;
}
time_t time(time_t *tloc);
功能:
获取时间 从1970年1月1日 00:00:00到现在经历多少秒
参数:
tloc time_t类型指针 保存秒数,可以传NULL
返回值:
成功 返回秒数 从1970年1月1日 00:00:00到现在经历多少秒
失败 -1
char *ctime(const time_t *timep);
功能:
时间转换函数 将time_t类型的时间转化为字符串
参数:
timep time_t指针
返回值:
成功 字符串格式的时间
struct tm *localtime(const time_t *timep)
功能:
将time_t类型的时间转化为struct tm*类型的时间
参数:
timep time_t* 类型
返回值:
成功 struct tm指针
失败 (void*)-1
struct tm {
int tm_sec; /* Seconds (0-60) */ 秒
int tm_min; /* Minutes (0-59) */ 分钟
int tm_hour; /* Hours (0-23) */ 时
int tm_mday; /* Day of the month (1-31) */ 日
int tm_mon; /* Month (0-11) */ 月
int tm_year; /* Year - 1900 */ 年
int tm_wday; /* Day of the week (0-6, Sunday = 0) */ 星期
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ 一年中第多少天
int tm_isdst; /* Daylight saving time */
};
#include
#include
int main()
{
time_t t; //time_t是long int类型
struct tm* tp;
t = time(NULL);
printf("time = %ld\n",t);
printf("ctime = %s\n",ctime(&t));
//转化 将秒数转化为年月日时分秒
tp = localtime(&t);
if ((void*)-1 == tp)
{
perror("localtime");
return 1;
}
printf("tm_sec %d\n", tp->tm_sec );
printf("tm_min %d\n", tp->tm_min );
printf("tm_hour %d\n", tp->tm_hour );
printf("tm_mday %d\n", tp->tm_mday );
printf("tm_mon %d\n", tp->tm_mon + 1 );
printf("tm_year %d\n", tp->tm_year+ 1900 );
printf("tm_wday %d\n", tp->tm_wday );
printf("tm_yday %d\n", tp->tm_yday );
//asctime函数
printf("asctime: %s\n", asctime(tp));
//gmtime函数
//转化 将秒数转化为年月日时分秒
tp = gmtime(&t);
if ((void*)-1 == tp)
{
perror("localtime");
return 1;
}
printf("tm_sec %d\n", tp->tm_sec );
printf("tm_min %d\n", tp->tm_min );
printf("tm_hour %d\n", tp->tm_hour + 8);
printf("tm_mday %d\n", tp->tm_mday );
printf("tm_mon %d\n", tp->tm_mon + 1 );
printf("tm_year %d\n", tp->tm_year+ 1900 );
printf("tm_wday %d\n", tp->tm_wday );
printf("tm_yday %d\n", tp->tm_yday );
return 0;
}
时间相关的函数根据manpage中的函数参数可返回值即可学会它们的使用
进程和程序:
单道与多道程序
并行和并发
MMU:
MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。
进程控制块PCB
进程的状态
在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。
在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态。
**①TASK_RUNNING:**进程正在被CPU执行。当一个进程刚被创建时会处于TASK_RUNNABLE,表示己经准备就绪,正等待被调度。
②TASK_INTERRUPTIBLE(可中断):进程正在睡眠(也就是说它被阻塞)等待某些条件的达成。一旦这些条件达成,内核就会把进程状态设置为运行。处于此状态的进程也会因为接收到信号而提前被唤醒,比如给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNABLE状态),然后再响应SIGKILL信号而退出(变为TASK_ZOMBIE状态),并不会从TASK_INTERRUPTIBLE状态直接退出。
③TASK_UNINTERRUPTIBLE(不可中断):处于等待中的进程,待资源满足时被唤醒,但不可以由其它进程通过信号或中断唤醒。由于不接受外来的任何信号,因此无法用kill杀掉这些处于该状态的进程。而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程,于是原有的流程就被中断了,这可能使某些设备陷入不可控的状态。处于TASK_UNINTERRUPTIBLE状态一般总是非常短暂的,通过ps命令基本上不可能捕捉到。
**④TASK_ZOMBIE(僵死):**表示进程已经结束了,但是其父进程还没有调用wait4或waitpid()来释放进程描述符。为了父进程能够获知它的消息,子进程的进程描述符仍然被保留着。一旦父进程调用了wait4(),进程描述符就会被释放。
**⑤TASK_STOPPED(停止):**进程停止执行。当进程接收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。当接收到SIGCONT信号,会重新回到TASK_RUNNABLE。
stat中的参数意义如下:
参数 | 含义 |
---|---|
D | 不可中断 Uninterruptible(usually IO) |
R | 正在运行,或在队列中的进程 |
S(大写) | 处于休眠状态 |
T | 停止或被追踪 |
Z | 僵尸进程 |
W | 进入内存交换(从内核2.6开始无效) |
X | 死掉的进程 |
< | 高优先级 |
N | 低优先级 |
s | 包含子进程 |
+ | 位于前台的进程组 |
l | 多线种进程(如CLONE_THREAD, NPTL ) |
常用选项:-aux 或 -ef
itcast@ubuntu:~/classcode/day05$ ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 1.3 168668 12808 ? Ss 00:44 0:03 /sbin/in
root 2 0.0 0.0 0 0 ? S 00:44 0:00 [kthread
root 3 0.0 0.0 0 0 ? I< 00:44 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 00:44 0:00 [rcu_par
root 6 0.0 0.0 0 0 ? I< 00:44 0:00 [kworker
可以搭配管道和grep使用,查看指定信息
itcast@ubuntu:~/classcode/day05$ ps -aux | grep bash
itcast 1500 0.0 0.5 8540 5352 pts/0 Ss+ 00:58 0:00 -bash
itcast 3689 0.0 0.5 8540 5320 pts/1 Ss 01:46 0:00 -bash
itcast 15277 0.0 0.0 6300 740 pts/1 S+ 08:52 0:00 grep --color=auto bash
itcast@ubuntu:~/classcode/day05$ top
top - 08:55:10 up 8:10, 2 users, load average: 0.00, 0.00, 0.00
Tasks: 190 total, 1 running, 189 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.
MiB Mem : 953.3 total, 119.1 free, 242.8 used, 591.4 buff/cache
MiB Swap: 1906.0 total, 1905.2 free, 0.8 used. 549.8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+
754 root 0 -20 161148 7012 6036 S 0.3 0.7 0:35.77
3461 root 20 0 0 0 0 I 0.3 0.0 0:43.65
3688 itcast 20 0 13924 5788 4312 S 0.3 0.6 0:00.41
15326 itcast 20 0 9248 3784 3260 R 0.3 0.4 0:00.02
1 root 20 0 168668 12808 8576 S 0.0 1.3 0:03.82
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00
# sleep second 可以使程序睡眠second秒,用于创建一个进程,并使用kill杀死
# 终端1
itcast@ubuntu:~/classcode/day05$ sleep 1000
Terminated
itcast@ubuntu:~/classcode/day05$ sleep 1000
Killed
itcast@ubuntu:~/classcode/day05$ sleep 1000
Killed
# 终端2
itcast@ubuntu:~/classcode/day05$ ps -aux | grep sleep
itcast 15451 0.0 0.0 5476 592 pts/0 S+ 08:59 0:00 sleep 1000
itcast 15460 0.0 0.0 6432 664 pts/1 S+ 09:00 0:00 grep --color=auto sleep
itcast@ubuntu:~/classcode/day05$ kill 15451
itcast@ubuntu:~/classcode/day05$ ps -aux | grep sleep
itcast 15470 0.0 0.0 5476 596 pts/0 S+ 09:00 0:00 sleep 1000
itcast 15474 0.0 0.0 6432 672 pts/1 S+ 09:00 0:00 grep --color=auto sleep
itcast@ubuntu:~/classcode/day05$ kill -9 15470
itcast@ubuntu:~/classcode/day05$ ps -aux | grep sleep
itcast 15479 0.0 0.0 5476 592 pts/0 S+ 09:00 0:00 sleep 1000
itcast 15481 0.0 0.0 6432 732 pts/1 S+ 09:00 0:00 grep --color=auto sleep
itcast@ubuntu:~/classcode/day05$ kill -SIGKILL 15479
例如:杀死sleep进程的三种方法
1. kill 进程号
2. kill -9 进程号
3. kill -SIGKILL 进程号
# 终端1
itcast@ubuntu:~/classcode/day05$ sleep 1000 &
[1] 15565
itcast@ubuntu:~/classcode/day05$ sleep 1000 &
[2] 15566
itcast@ubuntu:~/classcode/day05$ sleep 1000 &
[3] 15567
# 终端2
itcast@ubuntu:~/classcode/day05$ ps -aux | grep sleep
itcast 15565 0.0 0.0 5476 592 pts/0 S 09:04 0:00 sleep 1000
itcast 15566 0.0 0.0 5476 528 pts/0 S 09:04 0:00 sleep 1000
itcast 15567 0.0 0.0 5476 596 pts/0 S 09:04 0:00 sleep 1000
itcast 15571 0.0 0.0 6432 736 pts/1 S+ 09:04 0:00 grep --color=auto sleep
itcast@ubuntu:~/classcode/day05$ killall sleep
itcast@ubuntu:~/classcode/day05$ ps -aux | grep sleep
itcast 15583 0.0 0.0 6432 724 pts/1 S+ 09:04 0:00 grep --color=auto sleep
与fork搭配看效果
#include
#include
#include
int main()
{
pid_t pid = getpid();
printf("创建进程前:\n");
printf("pid = %d,ppid = %d,pgid = %d\n",
getpid(),getppid(),getpgid(pid));
fork();
printf("创建进程后:\n");
printf("pid = %d,ppid = %d,pgid = %d\n",
getpid(),getppid(),getpgid(pid));
return 0;
}
得到的结果因为子进程在结束之前父进程已经结束,从而子进程的父进程变为/bin/bash,同时getgpid返回
与fork搭配看效果
#include
#include
#include
int main()
{
pid_t pid = getpid();
printf("创建进程前:\n");
printf("pid = %d,ppid = %d,pgid = %d\n",
getpid(),getppid(),getpgid(pid));
fork();
printf("创建进程后:\n");
printf("pid = %d,ppid = %d,pgid = %d\n",
getpid(),getppid(),getpgid(pid));
return 0;
}
得到的结果因为子进程在结束之前父进程已经结束,从而子进程的父进程变为/bin/bash,同时getgpid返回