午夜稻草人

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

获取ID:

#include<unistd.h>

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

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

进程创建:

#include<unistd.h>

pid_t fork(void)

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

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

2.     在子进程中,返回0

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

例子:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
 
int main(void)
{
 pid_t pid;
 printf("Before fork .../n");
 
 switch(pid = fork()) {
 case -1:
   printf("Fock call fail/n");
   exit(1);
  
 case 0:
   printf("The pid of child is: %d/n", getpid());
   printf("The pid of child's parent is: %d/n", getppid());
   printf("Child exiting.../n");
   exit(0);
 
 default:
   printf("The pid of parent is: %d/n", getpid());
   printf("the pid of parent's child is: %d/n", pid);
 }
 printf("After fork, program exiting.../n");
 exit(0);
}

 

#include<unistd.h>

pid_t  vfork(void)

forkvfork的区别:

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

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

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

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

exec函数族:

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

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

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

看代码:

#include<unistd.h>
#include<stdio.h>
int main(void)
{
       printf("pid in main is %d\n",getpid());
       execl("/mnt/hgfs/share/program/process/getpid","getpid",NULL);
       printf("123\n");
       printf("pid in main is %d\n",getpid());
       return;
}

程序/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<unistd.h>

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

参数:

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

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

#include<unistd.h>

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

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

arg1—argn:与上面的相同。

#include<unistd.h>

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

参数:

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

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

代码:

#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main(void)
{
       int sel;
       char *argv[]={"ls","-al","/etc/passwd",(char *)0};
       scanf("%d",&sel);
       switch(sel)
       {
              case 1:
                     printf("execl\n");
                     execl("/bin/ls","ls","-al","/etc/passwd",(char *)0);
                     break;
              case 2:
                     printf("execlp\n");
                     execlp("ls","ls","-al","/etc/passwd",(char *)0);
                     break;
              case 3:
                     printf("execv\n");
                     execv("/bin/ls",argv);
                     break;
              case 4:
                     printf("execvp\n");
                     execvp("ls",argv);
                     break;
              default:
              return 0;
       }
}

#include<stdlib.h>

int  system(const  char *string)

功能:

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

代码:

#include<stdlib.h>
#include<stdio.h>
int main(void)
{
       printf("pid in main:%d\n",getpid());
       printf("ppid in main:%d\n",getppid());
       system("/mnt/hgfs/share/program/process/getpid");
       printf("test\n");
       return 0;
}

#./system

pid in main:31192

ppid in main:3432

pid=31193

ppid=31192

test

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

进程等待:

#include<sys/wait.h>

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绝对值的任一子进程。

 

posted on 2013-04-30 11:53  午夜稻草人  阅读(363)  评论(0编辑  收藏  举报