Chinaunix首页 | 论坛 | 博客
  • 博客访问: 385420
  • 博文数量: 96
  • 博客积分: 647
  • 博客等级: 上士
  • 技术积分: 490
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-29 22:15
文章分类
文章存档

2015年(1)

2014年(10)

2013年(26)

2012年(59)

我的朋友

分类:

2012-10-18 11:22:51

原文地址:Linux应用编程之进程编程 作者:xgmiao

进程同步:一组并发的进程按照一定的顺序执行的过程称为进程间的同步。

获取ID:

#include

pid_t  getpid(void)   //获取本进程ID

pid_t  getppid(void)  //在子进程中获取父进程ID

进程创建:

#include

pid_t fork(void)

fork()的奇妙之处在于它被调用一次,却返回两次,它可能有三种不同的返回值:

1.     在父进程中,返回新创建的子进程的PID

2.     在子进程中,返回0

3.     如果出现错误,返回一个负值。

#include

pid_t  vfork(void)

forkvfork的区别:

1.     fork:子进程拷贝父进程的数据段

vfork:子进程与父进程共享数据段

2.     fork:父、子进程的执行次序不确定

vfork:子进程先运行退出后,父进程再运行。

exec函数族:

exec被执行的程序替换调用它的程序。与fork的区别:

fork创建一个新的进程,产生一个新的PID

exec启动一个新程序,替换原有的进程,因此进程的PID不会改变。

看代码:

  1. #include<unistd.h>
  2. #include<stdio.h>
  3. int main(void)
  4. {
  5.        printf("pid in main is %d\n",getpid());
  6.        execl("/mnt/hgfs/share/program/process/getpid","getpid",NULL);
  7.        printf("123\n");
  8.        printf("pid in main is %d\n",getpid());
  9.        return;
  10. }

程序/mnt/hgfs/share/program/process/getpid就是打印出子进程和父进程的pid

$ #./execl

pid in main is 3724

pid=3724

ppid=3432

$# ps

PID TTY          TIME CMD

 3432 pts/1    00:00:00 bash

 3725 pts/1    00:00:00 ps

分析:可以看到我们的execl程序的进程IDgetpid的进程ID是一样的。而且他们的父进程都是shell命令。注意当getpid程序退出时,整个程序就退出了,所以后面的两个输出语句并没有执行。

#include

int  execl(const char *path,const char *arg1,...)

参数:

path:被执行的程序名(含完整路径)

arg1—argn:被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。

#include

int  execlp(const char *path,const char *arg1,...)

path:被执行程序名(不含路径,将从path环境变量中查找给程序)

arg1—argn:与上面的相同。

#include

int  execv(const char *path,char * const argv[])

参数:

path:被执行程序名(含完整路径)

argv[]:被执行程序所需的命令行参数数组(包括NULL).argv是指针数组

代码:

  1. #include<unistd.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. int main(void)
  5. {
  6.        int sel;
  7.        char *argv[]={"ls","-al","/etc/passwd",(char *)0};
  8.        scanf("%d",&sel);
  9.        switch(sel)
  10.        {
  11.               case 1:
  12.                      printf("execl\n");
  13.                      execl("/bin/ls","ls","-al","/etc/passwd",(char *)0);
  14.                      break;
  15.               case 2:
  16.                      printf("execlp\n");
  17.                      execlp("ls","ls","-al","/etc/passwd",(char *)0);
  18.                      break;
  19.               case 3:
  20.                      printf("execv\n");
  21.                      execv("/bin/ls",argv);
  22.                      break;
  23.               case 4:
  24.                      printf("execvp\n");
  25.                      execvp("ls",argv);
  26.                      break;
  27.               default:
  28.               return 0;
  29.        }
  30. }

#include

int  system(const  char *string)

功能:

调用fork产生子进程,由子进程通过exec来执行/bin/sh  –c  string来执行string所代表的命令。注意:这时在exec函数中,/bin/sh相当于程序名,而string为其参数。所以string命令的父进程是system

代码:

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. int main(void)
  4. {
  5.        printf("pid in main:%d\n",getpid());
  6.        printf("ppid in main:%d\n",getppid());
  7.        system("/mnt/hgfs/share/program/process/getpid");
  8.        printf("test\n");
  9.        return 0;
  10. }

#./system

pid in main:31192

ppid in main:3432

pid=31193

ppid=31192

test

可以看到getpid这条命令的父进程就是main进程。system就是一个系统调用,在system函数后面的代码必须等到调用所创建的子进程返回后才继续执行。其实在system的实现中其依次调用了forkexecwaitpid

进程等待:

#include

pid_t  wait(int *staloc);

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

调用waitwaitpid的进程可能:

1.     如果其所有子进程都还在运行,则阻塞。

2.     如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。

3.     如果它没有任何子进程,则立即出错返回。

其实,可以把wait函数理解为就是获取一个子进程的终止状态,终止状态存在staloc存储单元中。

waitpidpid参数的作用解释如下:

pid == -1   等待任一子进程。与wait等效。

pid >0     等待其进程IDpid相等的子进程。

pid =00    等待其组ID等于调用进程组ID的任一子进程。

pid <-1     等待其组ID等于pid绝对值的任一子进程。

阅读(723) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~