Linux之fork()相关知识

本文介绍了Linux中fork()函数用于创建子进程,子进程与父进程共享内存,采用写时拷贝策略降低开销。exec()系列函数用于替换进程执行内容,启动新程序。当子进程先结束时可能产生僵死进程,解决方法包括父进程使用wait函数或忽略SIGCHLD信号。
摘要由CSDN通过智能技术生成

1,基本概念:
Linux中的fork()的作用是复制进程,调用fork()之后会产生一个新的进程,称为子进程,被调用的进程称为父进程,两个进程的内容完全一样,语法如下:

pid_t pid = fork();//复制进程

该函数会返回一个int类型的返回值,如果pid等于0,则该进程是子进程,大于零的是父进程,失败的话返回值时-1。
2,写时拷贝(COW)
fork()之后父子进程指向相同的物理空间(内存区),如果父子进程只是对内存区的内容进行读取,就不用单独为子进程开辟新的物理空间,这样可以减少开销,称为写实拷贝。如果fork()之后立刻进行exec(),就不用为子进程单独开辟物理空间。
3,exec()函数
当我们想在希望子进程去执行另外的程序,exec函数就提供了一个在进程中启动另一个程序执行的方法。它可以通过文件名或者目录名找到对应的可执行程序,从而替换原来的进程中的内容。下面是exec函数的几种形式。exec函数成功不返回值,失败的情况返回-1。

int execl(const char* path, const char * arg,...);
int execlp(const char* file, const char * arg,...);
int execle(const char* path, const char * arg,...,char* const envp[]);
int execv(const char * path, char* const argv[]);
int execvp(const char * file, char* const argv[]);
int execve(const char * path, char* const argv[],char* const envp[]);

其中path就是指定可执行文件的目录名,file是文件名,argv[]存放的是参数列表。下面是对其中一个函数的使用,替换的是ps命令。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
int main()
{
	printf("main pid=%d\n",getpid());
	//execl 执行成功不返回,直接从新程序的主函数开始执行,只有失败才返回错误码
	execl("/bin/ps","ps","-f"(char*)0);
	perror("execl error");
	exit(0);
}

4,僵死进程
(1)产生的原因
当子进程先于父进程结束时,会产生僵死进程,此时子进程并没有结束,必须等到父进程获取了子进程的退出状态才真正结束。另外,如果父进程先退出,子进程会成为孤儿进程,最终会将给init进程处理,进程号为1。
(2)解决的方法
一是使用父进程使用wait函数获取子进程的退出状态,如果子进程没有退出,wait会阻塞。
二是使用信号处理,通过signal(SIGCHLD,SIG_IGN)通知内核对子进程的结束不关心,由内核回收,适用的场景是fork出大量的子进程,子进程结束现需要调用wait函数处理,如果忽视该信号,让内核将僵死进程交给init进程处理,节省了开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值