一个程序由一个或多个进程,每个进程作用不同,一个进程创建多个线程。
进程是资源分配的最小单位,每个进程都有自己独立的地址空间和执行状态。
进程创建:
1.分配一个id标识号,
2.复制父进程的环境
3.分配资源(程序、数据、用户栈)
4.复制父进改程地址空间
5.插入该进程进入就绪队列
进程撤销:
1.关闭软中断
2.回收资源
3.写记账信息
4.置该进程为僵死状态
5.重新分配CPU资源
一、复制一个进程映像fork
fork()函数,产生一个新的子进程,完全继承父进程的数据和堆栈空间等等,
若成功子进程返回0,父进程返回子进程ID。
区别在于
1.父进程的锁不继承
2.各自ID不同
#include<stdio.h>
int main()
{
int ret = 0;
ret = fork();
if(ret == 0)
{
printf("pid:%d\n",getpid());
}
else{
printf("pid:%d\n",getpid());
}
sleep(1);
return 0;
}
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pit= 0;
pit = fork();
if(pit == 0)
{
printf("111pit:%d,pid:%d\n",pit,getpid());
}
else {
printf("222pit:%d,pid:%d\n",pit,getpid());
}
pid_t pit2 = 0;
pit2 = fork();
if(pit == 0)
{
printf("333pit:%d,pid:%d\n",pit,getpid());
}
else {
printf("444pit:%d,pid:%d\n",pit,getpid());
}
sleep(1);
return 0;
}
二、写时复制copy on write
全局变量在子进程里发生改变是,子进程会复制一个全局变量进行值得改变。叫做写时复制。
#include<stdio.h>
#include<unistd.h>
int gval = 100;
int main()
{
printf("before fork pid = %d\n",getpid());
pid_t pid;
pid = fork();
if(pid > 0);
{
sleep(1);
printf("this is parent=%d childpid=%d gral=%d\n",getpid(),pid,gval);
sleep(3);
}
if(pid == 0)
{
gval++;
printf("this is parent=%d childpid=%d gral=%d\n",getpid(),pid,gval);
}
sleep(1);
return 0;
}
三、fork之后父子进程共享文件
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{
printf("before fork pid = %d\n",getpid());
int fd;
fd = open("test.txt",O_WRONLY);
if(fd == -1)
{
printf("error");
}
pid_t pid;
pid = fork();
if(pid > 0)
{
printf("this is parent pid=%d chaildpid=%d\n",getpid(),pid);
write(fd,"parent",6);
}
else if(pid == 0)
{
printf("this is parent pid=%d chaildpid=%d\n",getpid(),pid);
write(fd,"child",5);
}
sleep(1);
return 0;
}
char bufa[4096] = {0};
char bufb[4096] = {0};
memset(bufa,'A',sizeof(bufa));
memset(bufb,'B',sizeof(bufb));
write(fd,bufa,4096);
write(fd,bufb,4096);
四、vfork与fork
创建进程,优先运行子进程,父进程休眠状态。只有子进程exit后,父进程才会再恢复。
五、进程退出方式
·正常退出:
main()函数返回return
调用exit、_exit
exit会调用终止处理程序并清除I/O缓存,_exit不会。
·异常退出:
调用abort、由信号终止
六、atexit() 相当析构函数
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
void my_exit1()
{
printf("1111");
}
void my_exit2()
{
printf("2222");
}
int main()
{
atexit(my_exit1);
atexit(my_exit2);
return 0;
}
七、system命令
system(“ls -l”);
八、wait命令
宏定义 描述
WIFEXITED(status) 如果子进程正常结束,返回一个非零值。
WEXITSTATUS(status) 如果WIFEXITED非零,返回子进程退出码
if(WIFEXITED(status))
printf("child exited abnormal signal number=%d\n",WEXITSTATUS(status));
WIFSIGNALED(status) 子进程因为捕获信号而终止,返回非零值。
WTEDMSIG(status) 如果WIFSIGNALED非零,返回信号代码
if(WIFSIGNALED(status))
printf("child exited abnormal signal number=%d\n",WTEDMSIG(status));
WIFSTOPPED(status) 如果子进程被暂停,返回一个非零值
WSTOPSIG(status) 如果WIFSTOPPED非零,返回一个信号代码
if(WIFSTOPPED(status))
printf("child stoped signal number=%d\n",WSTOPSIG(status));
kil -l 查询信号
用signal忽略信号
signal(信号,函数 ) 当出现信号时执行函数
子进程结束运行时,它与父进程的关联还在,直到父进程正常结束或调用了wait才会终止。
ps aux |grep a.out 查看当前进程ID
0进程为系统进程,1进程为特殊进程init保留。
kill 进程ID 或者 kill a.out
cat /proc/sys/kernel/pid_max 查看最大进程数
ulimit -a 查看系统限制