setpgid()、getpgid()、setpgrp()和getpgrp()函数的使用说明

摘要:本文描述的是Linux手册页中setpgid()、getpgid()、setpgrp()和getpgrp()函数的使用说明.原文来自:http://www.kernel.org/doc/man-pages/.

setpgid()、getpgid()、setpgrp()和getpgrp()函数

NAME  

     setpgid()、getpgid()、setpgrp()和getpgrp()函数 - 设置或获取进程组ID.

SYNOPSIS

       #include
       int setpgid(pid_t pid, pid_t pgid);
       pid_t getpgid(pid_t pid);
       pid_t getpgrp(void);                 /* POSIX.1 version */
       pid_t getpgrp(pid_t pid);            /* BSD version */
       int setpgrp(void);                   /* System V version */
       int setpgrp(pid_t pid, pid_t pgid);  /* BSD version */
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
       getpgid():
           _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
       setpgrp() (POSIX.1):
           _SVID_SOURCE || _XOPEN_SOURCE >= 500 ||
           _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* Since glibc 2.19: */ _BSD_SOURCE
       setpgrp() (BSD), getpgrp() (BSD) [before glibc 2.19]:
           _BSD_SOURCE &&
               ! (_POSIX_SOURCE || _POSIX_C_SOURCE || _XOPEN_SOURCE ||
                  _XOPEN_SOURCE_EXTENDED || _GNU_SOURCE || _SVID_SOURCE)

DESCRIPTION

    在Linux系统上,这些接口都可以使用,用来设置或获取一个进程的进程组ID(PGID).按POSIX.1的规定,首选是:获取进程组ID(PGID),使用getpgid()函数,设置进程组ID(PGID),使用setpgid()函数.
    setpgid()函数将pid进程的进程组ID(PGID)设置为pgid.如果pid是0,则使用调用者的进程ID.如果pgid是0,则由pid指定的进程ID(PID)将用作进程组ID(PGID).如果使用setpgid()函数将某进程组的一个进程指定到另一个进程组,则要求两个进程组是属于同一个会话.在这种情况下,进程和进程组的会话(ID)相同,进程可以加入到由pgid指定的进程组中.
    在POSIX.1标准中,getpgrp()函数没有参数,返回一个进程的进程组ID.
    getpgid()函数,获取指定pid进程的进程组号(PGID).如果pid是0,表示获取当前进程的进程组号(PGID).(getpgid()函数获取进程组号PGID,除了需要调用者作为参数,其他并不需要,所以一般是选用getpgrp())
    在System V version中,setpgrp()函数不需要任何参数,等价于setpgid(0,0);
    在BSD version中,setpgrp()函数需要两个参数,库函数调用方式为setpgid(pid,pgid).
    自从glibc 2.19版本以后,setpgrp()函数不再公开,所以应该使用setpgid()函数替代setpgrp()函数.
    在BSD version中,getpgrp()函数需要一个参数,库函数调用方式为getpgid(pid).
    自从glibc 2.19版本以后,getpgrp()函数不再公开,所以应该使用POSIX.1规定中的无参数getprgp()函数调用替代getpgid(pid)函数调用(如果目的是为了获取进程组号(PGID)).或者使用getpgid(pid).

RETURN VALUE

    setpgid()和setpgrp()函数,成功返回0,失败返回-1,并设置errno的值.
    按POSIX.1的标准,getprpg()函数总是执行成功,返回调用者的进程组号(PGID).
    getpgid()函数和getpgrp()函数执行成功,返回一个进程组号的PGID,出错返回-1,并设置errno的值.

ERRORS

    EACCES 企图修改子进程的进程组号(PGID),但子进程已经调用了exec等系列函数的.
    EINVAL pgid参数小于0.(setpgid(),setpgrp())
    EPERM 权限不满足,无法调用修改.企图将一个进程添加到一个会话号不同的进程组,或者修改一个不同会话号的子进程组的进程组号(PGID),或者是讲一个进程组号(PGID)设置为会话首进程.(setpgid(),setpgrp())
    ESRCH 对于getpgid(),找不到pid进程.对于setpgid(),pid不是当前进程,也不是其子进程.

CONFORMING TO

    setpgid()和无参数getpgrp()都遵守POSIX.1-2001标准.
    POSIX.1-2001标准也规定了getpgid()和无参数的setpgrp().
    一个参数的getpgrp()和两个参数的setpgrp() 是在4.2BSD规定的,而不是在POSIX.1.


NOTES

    通过fork()函数产生的子进程会继承它的父进程的进程组ID(PGID),进程组ID(PGID)靠execve()函数维护.
    如果进程组是会话的一员,则进程组的进程也是会话的一员.
    一个会话可以拥有一个控制终端,会话有一个前台进程组,会话的其他进程组则为后台进程组.
    在任何时候,如果在终端键入一个信号(比如终端信号),就会将该信号发送给前台进程组的所有进程.
    只有前台进程组的进程才可以从终端读取数据;如果后台进程组的进程尝试从终端读取数据,进程组会发送一个SIGTTIN信号,中断该操作.
    函数tcgetpgrp()和tcsetpgrp()用来获取或设置前台进程组的控制终端.
    为了实现控制终端的任务,通常用函数setpgid()和getpgrp()在shell下创建一个进程组.
   如果终端接口监测到调制解调器已经断开连接,则将挂断信号发送给控制终端进程(会话首进程).如果会话首进程存在,则中断信号也将被发送给每一个控制终端的前台进程组中的进程.
    如果由于某进程退出导致该进程组成为孤儿进程组,该孤儿进程组中处于停止状态的进程将会先发送一个SIGCONT信号再发送SIGHUP信号.进程组中进程的父进程都是当前进程组中的进程,或者是其他会话中进程,这样的进程组称之为孤儿进程组.

END

笔者:个人能力有限,只是学习参考...读者若发现文中错误,敬请提出.
-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------勿在浮沙筑高台,静下心来,慢慢地沉淀---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

你可能感兴趣的:(GNU/Linux环境编程,GNU/Linux环境高级编程,setpgid函数,getpgid函数,setpgrp函数,getpgrp函数,Linux)