本文从整体上介绍linux进程的相关知识点,以及应该知道和了解的点,对于某些简单的点,会在框图下面给出解释,对于复杂的内容,会以单独的篇幅详细解释。

  • 右键可以单独打开图片

进程需要掌握的点如上图所示,左边是一些进程涉及到的知识点,右边是应知应会的一些API函数,这里边需要有几个点注意:

进程地址空间

wait返回后判断子进程退出状态

这部分内容应该是man手册里面的,不应该出现在这里。。。
示例程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

#define ERR_EXIT(m) \
	do{\
		perror(m);\
		exit(EXIT_FAILURE);\
	}while(0)

int main()
{
	pid_t pid;
	int ret = 0;
	int status;
	
	pid = fork();
	if (pid == -1)
	{
		ERR_EXIT("fork error :");
	}
	if (pid == 0)
	{
		printf("this is child %d \n",getpid());
		exit(10);
		//abort();
	}
	ret = wait(&status);
	if (ret == -1)
	{
		ERR_EXIT("wait error :");
	}
	if (WIFEXITED(status)) // 正常退出
	{
		printf("正常退出 : %d\n", WEXITSTATUS(status));
	}
	else if (WIFSIGNALED(status)) // 异常退出
	{
		printf("异常退出 : %d\n", WTERMSIG(status));
	}
	else if (WIFSTOPPED(status)) // 进程停止
	{
		printf("进程停止 : %d\n", WSTOPSIG(status));
	}
	return 0;
}

父进程等待子进程退出的问题

  • 父进程等待子进程退出有两个点需要注意一下,一是wait函数在有一个子进程返回时会立马返回,在多个子进程的情况下会导致其他的子进程没有收尸,二是wait调用的可中断睡眠,在接收到信号时,wait函数也会返回,需要作进一步判断。。。

示例程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

#define ERR_EXIT(m) \
	do{\
		perror(m);\
		exit(EXIT_FAILURE);\
	}while(0)

int main()
{
	pid_t pid;
	int ret = 0;
	int i;
	int num;

	printf("请输入子进程个数:");
	scanf("%d",&num);
	
	for (i=0; i<num; i++)
	{
		pid = fork();
		if(pid == -1)
		{
			ERR_EXIT("fork error :");
		}
		if (pid == 0)
		{
			printf("this is child %d \n",getpid());
			sleep(1);
			exit(0);
		}
	}
	/* 收尸所有的僵尸进程 */
	while(1)
	{
		ret = wait(NULL);
		printf("子进程退出,mypid \n");
		if (ret == -1)
		{
			if(errno == EINTR)	// 父进程阻塞过程中可能被别的信号中断
			{
				continue;
			}
			break;
		}
	}
	printf("父进程退出 ....\n");
	return 0;
}
  • 父进程创建了n个子进程,子进程先退出,父进程收尸,调用wait收尸所有的子进程,在阻塞期间可能会由别的信号使wait返回,应该判断errno的值并继续等待,运行结果:

sleep不可中断写法

sleep函数会将进程进行休眠,但是sleep函数属于可中断睡眠,在进程接收到信号之后会立刻返回,返回值为剩下的秒数,利用这个特点,可以让sleep在接收到信号之后继续睡眠,直到睡眠时间结束为止。

示例程序

do{
	n = sleep(10);	// 返回剩余的秒数  可中断睡眠
	printf("keep sleeping ... \n");
}while(n>0);

进程里面还有一些有料的点,后面单独讲。。。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

信号 上一篇
UNIX环境编程概述 下一篇