1.进程的基本概念
进程是可执行文件,是系统资源调度的基本单位,进程由数据,代码,和堆栈组成。
2.创建进程
fork函数可创建父子进程,当前进程是父进程,被创建进程是子进程,创建完之后父子进程通知执行拷贝方式来创建,fork函数创建子进程,子进程拷贝父进程的所有代码并且记录进程上下文(运行到啥时候了),父进程的fork返回子进程id,子进程的fork返回0。
下面创建了一个父子进程实现父进程打印当前时间,子进程实现随机数
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int main()
{
if(fork())//fork为真,返回的是子进程id,所以true为父进程
{
struct tm *time;
time_t tt;
while(1)
{
tt=time(0);
time=localtime(tt);
printf("%d:%d:%d",time->tm_hour,time->tm_min,time->tm_sec);
sleep(1);
}
}
else
{
srand(time(0));
while(1)
{
printf("-----%05d-----",rand()%50000);
sleep(1);
}
}
return 0;
}
3.僵尸进程
父进程创建了子进程,父进程先于子进程结束,子进程资源没有被释放,就会变成僵尸进程,持续占用系统资源(内核中有一颗树,树节点是进程数据 进程本身资源).子进程结束前,会向父进程发送 SIGCHLD信号,父进程收到信号后,回收子进程资源,然后父进程再结束.在父进程创建后可使用wait函数来避免僵尸进程.
4.守护进程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
int main(){
//1. 重设文件权限 umask
umask(0);
//2. 创建子进程 fork
int ret = fork();
if(ret<0) printf("创建进程失败:%m"),exit(-1);
if(ret>0) printf("父进程结束:%m\n"),exit(0);//3. 让父进程结束
if(0 == ret){
printf("pid:%d\n",getpid());
//4. 创建新会话 setsid
setsid();
//5. 防止子进程成为僵尸进程 忽略掉SIGCHLD SIGHUP信号
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);
//6. 改变当前工作目录 chdir
chdir("/");
//7. 重定向文件描述符号 open dup2(fd,0) dup2(fd,1)
int fd = open("/dev/NULL",O_RDWR);
dup2(fd,0);
dup2(fd,1);
}
while(1){
sleep(1);//模拟守护进程工作
}
return 0;
}