Linux应用编程之进程编程

来源:互联网 发布:音乐加快节奏软件 编辑:程序博客网 时间:2024/05/14 18:52

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

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

原创粉丝点击