进程控制的函数


pid_t fork
void);
          功能:创建一个新进程
         返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
注:
  • fork之后是父进程还是子进程先执行是不确定的,取决于内核的调度算法。
  • 父子进程共享代码段,至于数据段、栈段、堆并不对父进程完全复制,作为替代,使用写时复制技术。这些区域由父子进程共享,内核将他们的访问权限变为只读。如果父子进程中的任何一个试图修改这些区域。则内核只为修改区域的那块内存制作一个副本。通常是虚拟存储系统中的一页。
  • 父进程中所有打开文件描述符都被复制到子进程中。父子进程每个相同的文件描述符共享一个文件表项。
pid_t vforkvoid);
          功能:创建一个新进程
         返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
         注:
  • vfork并不将父进程的地址空间完全复制到子进程中,在调用exec或exit之前它在父进程空间中运行。与父进程共享代码段,数据段,堆栈等。
  • vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。
  • 它产生的子进程刚开始暂时与父进程共享地址空间(其实就是线程的概念了),因为这时候子进程在父进程的地址空间中运行,所以子进程不能进行写操作,并且在儿子“霸占”着老子的房子时候,要委屈老子一下了,让他在外面歇着(阻塞),一旦儿子执行了exec或者exit后,相当于儿子买了自己的房子了,这时候就相当于分家了。
  • vfork和fork之间的另一个区别是: vfork保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。由此可见,这个系统调用是用来启动一个新的应用程序。其次,子进程在vfork()返回后直接运行在父进程的栈空间,并使用父进程的内存和数据。这意味着子进程可能破坏父进程的数据结构或栈,造成失败。
pid_t wait (int * status);
功能:使父进程阻塞,等待任一子进程结束。一旦任何一个子进程终止,则取得盖子进程的终止状态并立即返回;
参数:status  保存子进程的终止状态
返回值:如果它没有任何子进程,则立即出错返回-1.成功返回已终止的子进程PID;
注:
  • 进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
  • status是由实现定义的,其中某些位表示退出状态(正常返回),其他位表示信号编号(异常返回)。有一位指示是否产生了core文件。

pid_t waitpid(pid_t pid,int * status,int options);
功能:使父进程阻塞,等待特定子进程结束。
参数:
               pid:
                 pid==-1 等待任一子进程结束,就这一方面,waitpid和wait等效
                 pid<-1   等待其组ID为pid绝对值的任一子进程。主要是父子进程不在同一组进程中。
                 pid==0   等待其组ID等于调用进程组ID的任一子进程,主要是父进程与子进程在同一组进程中。
                 pid>0     等待其进程ID与pid相等的子进程
               status:保存子进程的终止状态
               options:
                    WNOHANG 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若结束,则返回该子进程的ID。
                    WUNTRACED 若由pid指定的子进程进入暂停状态,并且其状态自暂停以来还未报告过,则马上返回其状态。
                    WCONTINUED 若由pid指定的子进程在暂停后已经继续,但其状态尚未报告,则返回其状态。
         返回值: 出错返回-1.成功返回已终止的子进程PID;
         注:
  • 子进程正常结束,exit或_exit或Exit返回其退出状态。异常终止,内核产生一个终止状态
  • 子进程的结束状态返回后存于 status,底下有几个宏可判别结束情况:
WIFEXITED(status)如果若为正常结束子进程返回的状态,则为真;对于这种情况可执行WEXITSTATUS(status),取子进程传给exit或_eixt的低8位。
WEXITSTATUS(status)取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。
WIFSIGNALED(status)若为异常结束子进程返回的状态,则为真;对于这种情况可执行WTERMSIG(status),取使子进程结束的信号编号。
WTERMSIG(status) 取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。
WIFSTOPPED(status) 若为当前暂停子进程返回的状态,则为真;对于这种情况可执行WSTOPSIG(status),取使子进程暂停的信号编号。
WSTOPSIG(status) 取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。




pid_t getpid(void);
功能:获得当前进程ID
返回值:当前进程ID,此函数总是成功
       

pid_t getppid(void);
功能:获得父进程ID
返回值:父进程ID,此函数总是成功

char *getenv(const char *name)
功能:获得环境变量
参数:name:想要获得的环境变量的名字
返回值:返回指向环境变量的指针,没有匹配的环境变量时返回NULL
例:getenv("PATH");


int  getdtablesize(void);
       功能: 返回当前进程能够打开的最大文件描述符个数。


pid_t  g etpgrp(void);  
        功能:返回调用进程的组ID

pid_t getpgid(pid_t pid)
         功能:返回进程ID为pid的组ID,若pid=0.则返回调用进程组ID
          返回值:出错返回-1

int  setpgid(pid_t  pid,pid_t  pgid)
          功能:将pid进程的进程组ID设置为pgid,如果这两个参数相等,则由pid指定的进程变成进程组组长。如果pid是0,则使用调用进程的进程ID。另外,如果pgid是0,则由pid指定的进程ID用作进程组ID。
         一个进程只能为它自己和子进程设置组ID。
         返回值:成功返回0,错误返回-1.





例程:
int main()
{
pid_t pid;
int  status;
int pids[3];
int i = 0;

for(i = 0; i < 3; i ++)
{
pid = fork();
if (pid > 0) //father process
{
pids[i] = pid;
printf("new child [%d]\n", pid);
}
else if (pid == 0) //child process
{
puts("I`m child, I`m going to die");
if(i == 1)
sleep(3);
sleep(1);
exit(20);
}
else
error(EXIT_FAILURE, errno, "fail to fork --->%s:%s:%d\n",
__FILE__, __func__, __LINE__);
}

for(i = 0; i < 3; i ++)
printf("%d\n", pids[i]);
puts("I`m father, waiting for child died ... ...");
waitpid(pids[1], &status, 0);
printf("child %d is dead with [%d]\n", pids[1], WEXITSTATUS(status));
exit(EXIT_SUCCESS);
}








































































































     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值