《linux网络编程》 -- 【第一天】进程exec 和fork()的联用

1. 系统调用exec 和fork()联合

 系统调用exec 和fork()联合起来为程序员提供了强有力的功能。我们可以先用fork()建立子进程,然后在子进程中使用exec,这样就实现了父进程运行一个与其不同的子进程,并且父进程不会被覆盖。

2. 例程

  #include <stdio.h>
  #include <unistd.h>
  main()
  {
   int pid;
   /* fork 子进程 */
   pid=fork();
   switch(pid) 

   {
    case -1:
     perror("fork failed");
      exit(1);
    case 0:
      execl("/bin/ls","ls","-l","--color",NULL);
      perror("execl failed");
      exit(1);
    default:
      wait(NULL);
      printf("ls completed\n");
      exit(0);
    }
  }

 A 是父进程,它正在执行系统调用wait(),使进程A 睡眠,直至子进程B 结束。


3. fork()、文件和数据:
子进程可用的数据是父进程可用数据的拷贝,并且其占用不同的内存地址空间


父进程中已打开的文件,在子进程中也已被打开,子进程支持这些文件的文件描述符;
子进程与父进程公用这些文件的文件指针,文件指针由系统保存;

4.exec()和打开文件
在程序中已被打开的文件,其在新程序中仍保持打开,文件的指针也不会被exec 调用改变。


执行关闭位(close-on-exec ),该位被设置的话,则调用exec 时会关闭相应的文件。该位的默认值为非设置。fcntl 能用于对这一标志位的操作。


   fcntl(fd,F_SETFD,1);


如果已经设置了执行关闭位,我们可以用下面的语句来撤销“执行关闭“位的设置,并取得它的返回值:
   

    res=fcntl(fd,F_SETFD,0);


如果文件描述符所对应的文件的“执行关闭位”已经被设置,则res 为1,否则res 值为0。

5.进程的终止
   void exit(int status);
如果成功,则返回0;如果出错,则返回非0 值。
它将关闭所有已打开的文件。如果父进程因执行了wait()调用而处于睡眠状态,那么子进程执行exit()会重新启动父进程运行。另外,exit()还将完成一些系统内部的清除工作,例如缓冲区的清除工作等。


   void _exit(int status)
使用方法与exit()完全相同,但是它执行终止进程的动作而没有系统内部的清除工作。

4. 进程的同步
函数库sys/wait.h 中的函数声明如下:
 pid_t wait(int *status)


当子进程执行时,wait()可以暂停父进程的执行,
如果有多个子进程在执行,那么父进程中的wait()在第一个子进程结束时返回,恢复父进程执行。


wait()的返回值通常是结束的那个子进程的进程标识符。如果wait()返回-1,表示没有子进程结束,这时errno 中含有出错代码ECHILD。


如果参数用了null 指针,wait 就忽略它。如果参数是一个有效的指针,那么wait 返回时,该指针就指向子进程退出时的状态信息。通常,该信息就是子进程通过exit 传送出来的出口信息
通过exit 返回给父进程之值存放在exit_status 的低位中,(注意,在整型量中,低8 位在前,高8 位在后)。如果它们不为0,表示该子进程是被另一个进程用一种称为信号的通信机构停止的,而不是通过exit()结束的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值