栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

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

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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_SUCCESS和EXIT_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
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)命名管道:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/881992.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号