Linux编程基础:6.2+8.1.1 学习记录

1.exec函数族:

        功能是:根据指定的文件名或路径,找到可执行文件,用该文件取代调用该函数的进程中的程序,再从该文件的main()函数开始执行文件的内容。一般与fork()函数一起使用,fork()创建进程,exec函数族修改进程任务,进程pid不变。

        一个进程调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序代码,废弃原有数据段和堆栈段,并为新程序分配新数据段与堆栈段。

exec函数族中包含6个函数,包含在系统库unistd.h中,其声明分别为:

execl类:

int execl(const char *path, const char *arg, ...,NULL);
int
execlp(const char *file, const char *arg, ...,NULL);
int
execle(const char *path, const char *arg, ..., char * const envp[]);

execv类:
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,传入数据为路径名或可执行文件名;第二个参数分为execl类(函数将以列举的形式传入参数,由于参数列表的长度不定,所以要用哨兵NULL表示列举结束)和execv类(函数将以参数向量表传递参数,char * argv[]的形式传递文件执行时使用的参数,数组中最后一个参数为NULL);如果没有参数char * const envp[],则采用默认环境变量;如果有,则用传入的参数替换默认环境变量。

        返回值:调用成功没有返回值。

2.exit()函数 和 _exit()函数:

        exit()和_exit()函数都是用来终止进程,调用_exit()时,系统会无条件停止操作,终止进程并清除进程所用内存空间及进程在内核中的各种数据结构;而exit()是对_exit进行了包装,在调用_exit()之前先检查文件的打开情况,将缓冲区中的内容写回文件。存在于系统库stdlib.h中,其声明如下:

void exit(int status);
void
_exit(int status);

        参数:status表示进程的退出状态(0表示正常退出,非零表示异常退出),为了可读性,标准C定义了两个宏(EXIT_SUCCESSEXIT_FAILURE)分别表示正常退出异常退出

3.wait()函数 和 waitpid()函数:

        (1)wait()函数功能是:挂起进程,进程进入阻塞状态,直到子进程变为僵尸态,如果捕获到子进程的退出信息就会转为运行态,然后回收子进程资源并返回;若没有变为僵尸态的子进程,wait函数就会让进程一直阻塞。若当前进程有多个子进程,只要捕获到一个变为僵尸态的子进程,wait函数就会恢复执行态。函数存在于sys/wait.h中,其声明如下:

pid_t wait(int *status);

        参数:status是一个int *类型的指针,用来保存子进程退出时的状态信息。通常情况下该参数设为NULL,表示不关心进程是如何终止的。

        返回值:调用成功返回进程id,失败返回-1并设置errno为ECHILD

        若wait函数的参数不为空,可以获取子进程的退出状态,退出状态存放在参数status的低八位中。Linux定义了一组判断进程退出状态的宏函数,其中最基础的两个是:

#include <sys/wait.h>
int WIFEXITED(int status);//判断子进程是否正常退出,若是,返回非0值,否则返回0
int WEXITSTATUS(int status);//若WIFEXITED返回非零值,用来提取子进程的返回值。

        (2)当前进程有很多个子进程,wait函数无法保证所有子进程在父进程之前执行。而waitpid函数可以应对 wait函数面临的缺点。可以等待指定的子进程,也可以在父进程不阻塞的情况下获取子进程的状态。函数存在于sys/wait.h中,其声明如下:

pid_t waitpid(pid_t pid, int *status, int options);

        参数:pid一般是进程的pid,也有可能是其他取值:pid > 0:等待子进程(编号为pid)退出,若退出,函数返回;若未结束,则一直等待;pid = 0:等待同一进程组的所有子进程退出,若某子进程加入了其他进程组,则waitpid不再关心它的状态;pid = -1:waitpid函数退化为wait函数,阻塞等待并回收一个子进程;pid < -1:等待指定进程组中的任何子进程,进程组的id等于pid的绝对值。

        status是一个int *类型的指针,用来保存子进程退出时的状态信息。通常情况下该参数设为NULL,表示不关心进程时如何终止的。(同wait一样)

        options 提供控制选项,可以是一个常量 0,表示不使用选项;也可以是管道“|”连接的两个常量,WNOHANG,如果子进程没有终止,waitpid不会阻塞父进程,会立即返回;WUNTRACED,如果子进程暂停执行,waitpid立即返回。

        返回值:正常返回是子进程的id;若options = WNOHANG, waitpid发现没有已退出的子进程可回收时返回0;出错返回-1并设置errno

4.特殊进程:

        孤儿进程:父进程负责回收子进程,如果父进程在子进程退出之前退出,子进程就会变成孤儿进程,此时init进程将代替父进程完成子进程的回收工作。
        僵尸进程:调用exit函数后,该进程不会马上消失,而是留下一个称为僵尸进程的数据结构。它几乎放弃进程退出前占用的所有内存,既没有可执行代码也不能被调度,只是在进程列表中保留一个位置,记载进程的退出状态等信息供父进程回收。若父进程没有回收子进程的代码,子进程将会一直处于僵尸态。

        注意事项:1.僵尸进程不能再次被运行,会占用一定的内存空间,并占据进程编号,当僵尸进程较多时,将会消耗系统内存,新进程可能因内存不足或无法获取pid而无法创建;2.父进程通过wait()和waitpid()函数可以有效防止僵尸进程的产生,对于已存在的僵尸进程,则可通过杀死其父进程的方法解决;3.当僵尸进程的父进程被终止后,僵尸进程将作为孤儿进程被init进程接收,init进程会不断调用wait()函数获取子进程状态,对已处于僵尸态的进程进行处理;4.孤儿进程永远不会成为僵尸进程。

5.管道:

        管道其实质是由内核管理的一个缓冲区,数据只能从一端传送到另一端,被设计为环形的数据结构。形象地认为管道的两端连接着两个进程:一个进程进行信息输出,将数据写入管道;另一个进程进行信息输入,从管道中读取信息。管道分为匿名管道和命名管道。

        (1)匿名管道:在进程中创建的管道,在进程退出后会被销毁。使用时进程无需关心管道在内存中的位置,通过亲缘关系连接,因此只能用于有亲缘关系的进程间。

        函数pipe()用来创建匿名管道,函数存在于unistd.h中,,其声明如下:

int pipe(int pipefd[2]);

        参数:传入参数pipefd为一个文件描述符数组;Linux将管道抽象为一个特殊文件。

        返回值:调用成功返回0,失败返回-1。

        父进程进行读操作,子进程进行写操作,使用close()函数关闭进程的读或写端口。

        重定向函数dup2()将参数oldfd的文件描述符复制给newfd,函数存在于unistd.h库中,其声明如下:

int dup2(int oldfd, int newfd);

返回值:若函数调用成功则返回newfd;否则返回-1并设置errno

        (2)命名管道:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值