Linux父子进程的一些常见问题

使用fork()函数可以创建一个子进程,这个函数的特殊之处在于,调用一次会返回两次,父进程一次子进程一次,返回值可能的取值如下:

  • 1)在父进程中,fork返回新创建子进程的进程ID;
  • 2)在子进程中,fork返回0;
  • 3)如果出现错误,fork返回一个负值;

执行过fork后,子进程中的操作就与父进程无关了,父进程可以通过wait/waitpid函数来获取子进程的状态。

父进程需要关注一下僵尸进程,通过signal函数监听SIGCHLD信号来调用wait/waitpid函数回收子进程是一种比较常用的解决方法,或者直接在父进程中wait/waitpid阻塞等待子进程退出也可以。

关于wait和waitpid函数,简单说就是wait是一种特殊的waitpid函数,waitpid提供了三个参数,比wait函数多了两个参数:pid和options,关于差别可以参考如下博文
进程同步
在这里插入图片描述

如果想要获取子进程中某些操作的执行结果,则需要进行进程间通信(IPC),linux中可以实现进程间通信的方法有很多,比如:管道、信号、消息队列、共享内存、socket套接字等,这里我需要通信的进程是父子进程,直接使用匿名通道比较便利,所以我采用匿名通道来进行简单的通信,示例代码如下:

int Test()
{
	int fd[2]; // 创建子进程前定义两个文件描述符作为管道的读端和写端
	int ret = pipe(fd); // 创建管道
	if (ret == -1) {
		return -1;
	}
	int childPid = fork(); // 创建子进程
	if (childPid == 0) { // fork返回值为0对应的是子进程
		printf("I am child!!!!\n");
		char *buf = "hello, father";
		close(fd[0]); // 关闭子进程读端
		write(fd[1], buf, strlen(buf) + 1); // 往写端写入数据
		close(fd[1]);
		exit(0); // 退出子进程
	} else if (childPid > 0) { // fork返回值大于0对应的是父进程,返回值为子进程pid
		printf("I am father!\n");
		printf("The pid of child is %d\n", childPid);
		close(fd[1]); // 关闭父进程写端
		char recvbuf[10] = { 0 };
		read(fd[0], recvbuf, sizeof(recvbuf)); // 读取子进程写入管道的数据
		printf("%s\n", recvbuf);
		close(fd[0]);		
	} else { // fork返回值小于0表示出错
		return -1;
	}
	return 0;
}

示例代码是子进程往父进程写消息,如果需要父进程往子进程写可以调换使用的描述符。

关于使用管道来实现进程通信的详细介绍,可以参考如下博文
匿名管道

设置子进程的工作目录

子进程中使用execv运行其他可执行程序,程序的工作目录是与父进程一致的,为了让工作目录改为子进程运行程序的实际运行位置,可以使用chdir函数来修改运行目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值