评论

收藏

[Unix] UNIX系统编程小结(三)----进程相关

服务系统 服务系统 发布于:2021-07-01 09:26 | 阅读数:350 | 评论:0

        进程即一个程序的动态执行。引用apue上的一句话:"A thorough understanding of the UNIX System's process control is essential for advanced programming".
  一.总述
  1.进程的开始
  在C语言中,进程是由一个main函数开始。
int main(int argc,char *argv[])
  我们可以向程序传入参数,以字符串数组的形式存储在argv,同时argc记录传入参数的个数。而且还可以在main的第三个参数中传入环境变量的数组,但一般不这样做。用全局environ更好。
    2.进程中
  在一个正在执行的进程中,可以fork出子进程(copy 出一个进程),也可以vfork出子进程(与新的进程share地址空间),同时父进程需要wait子进程,否则子进程就会变成僵尸进程,无家可归。我们还可以用exec function进行替换程序(但进程ID不变)。在一个进程中,system()可以执行一个shell命令,但要注意system对set-user-ID会造成权限的传递,这一点在后面会详细叙述。
  3.进程结束
  进程的结束有很多种方式,大致可以分为正常结束与异常结束。具体的我就不赘述了。主要解释exit,_exit,_Exit的区别。_exit,_Exit在结束的时候不会fllush缓冲,而exit在结束时会fllush缓冲,而且在某些UNIX系统中,exit还会关闭标准I/O流,以及与标准I/O流相关联的STDOUT_FILENO与STDIN_FILENO文件描述符。在这样的情况下,只需要用dup先复制文件描述符就可以了。
  二.system call 以及 一些知识点
  我喜欢用函数来总结知识点。
          1.atexit()。可以使用atexit()来注册若干个exit handler,参数是函数的地址。当进程结束时,就会执行每一个注册了的exit handler,即执行函数。但要注意,这个执行顺序是栈的顺序,也就是"先注册,后执行"。比如说,当我做完一件事(即exit时),我先注册的A执行funcA_1,再注册的B执行funcB_2,最后注册的A执行funcA_3。但最后的执行顺序却是反的。程序如下:
  
1 #include <apue.h>
 2 
 3 static void funcA_1()
 4 {
 5   printf("funcA_1\n");
 6 }
 7 static void funcB_2()
 8 {
 9   printf("funcB_2\n");
10 }
11 static void funcA_3()
12 {
13   printf("funcA_3\n");
14 }
15 
16 int main()
17 {
18   if(atexit(funcA_1)!=0)
19     err_sys("I can't register funcA_1");
20   if(atexit(funcB_2)!=0)
21     err_sys("I can't register funcB_2");
22   if(atexit(funcA_3)!=0)
23     err_sys("I can't register funcA_3");
24   exit(0);
25 }
  
  执行结果如下:
  ?

  
关注下面的标签,发现更多相似文章