Linux 常用的 C 语言进程 API
Last Update:
daemon
1 |
|
快速创建希望脱离控制台,以守护进程形式在后台运行的程序。
将进程的工作目录改为根目录,STDIN
, STDOUT
, STDERR
都重定向到 /dev/null
。随后 fork 一个子进程。
假如运行成功,父进程在 daemon
函数运行完毕后自杀,以后的代码全部是子进程来运行。
守护进程
守护进程(daemon)是运行在后台,且一直运行的一种特殊进程。它独立于控制终端并周期性执行某种任务或者等待处理某些事件。它是一种很有用的进程,Linux 的大多数服务器就是用守护进程实现的,守护进程也完成许多系统任务。
nochdir
当为真(非 0 值)时,不把进程的工作目录改为根目录。
noclose
当为真(非 0 值)时,不重定向标准输入输出。
返回值
成功则在子进程中返回 0,在父进程中不返回。失败则返回 -1,失败原因存于 errno
中。
exec 函数族
系统调用 exec 有多种使用形式,称为 exec 函数族。它们只是在参数上不同,功能是相同的。
exec 函数族中有 6 个函数,分别为 execl
、execv
、execle
、execve
、execlp
、execvp
。函数中最后一个字母 l、v 分别表示参数用列表传递、参数用字符指针数组传递,e、p 分别表示可指定环境变量、可自动搜索文件。
exec 函数族与 fork
函数不同。fork
产生一个新的进程,而 exec 函数族则是直接替换掉当前进程。如果你希望程序创建一个新的进程用于运行指定程序,你需要先 fork 一个新的子进程,再在子进程中调用 exec。
execl
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
path
要执行的文件路径。
arg
执行时传入的参数,可以有多个。最后一个参数必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
execle
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
path
要执行的文件路径。
arg
执行时传入的参数,可以有多个。最后一个参数必须用空指针 NULL
作结束。
envp
执行时传入的环境变量,是一个数组。最后一个环境变量必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾;PATH=/bin:/usr/bin
、TERM=xterm
两个字符串作为环境变量,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
execlp
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
file
要执行的文件名,系统会自动在环境变量 PATH
指定的各目录中搜索该文件。
arg
执行时传入的参数,可以有多个。最后一个参数必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
execv
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
path
要执行的文件路径。
argv
执行时传入的参数,是一个数组。最后一个参数必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
execve
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
path
要执行的文件路径。
argv
执行时传入的参数,是一个数组。最后一个参数必须用空指针 NULL
作结束。
envp
执行时传入的环境变量,是一个数组。最后一个环境变量必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾;PATH=/bin:/usr/bin
、TERM=xterm
两个字符串作为环境变量,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
execvp
1 |
|
将当前进程的程序替换为指定的程序,然后执行该程序。
file
要执行的文件名,系统会自动在环境变量 PATH
指定的各目录中搜索该文件。
argv
执行时传入的参数,是一个数组。最后一个参数必须用空指针 NULL
作结束。
示例:
1 |
|
此处传入了 ls
、-al
、/etc/passwd
三个字符串作为参数,并以 NULL
结尾。
返回值
如果执行成功则函数不会返回,执行失败则直接返回 -1,失败原因存于 errno
中。
fork
1 |
|
建立一个新的进程并作为子进程运行。将会拷贝父进程的程序、变量等几乎全部内存数据,并在父进程和子进程的程序上下文中返回不同值。
返回值
成功则在子进程中返回 0,在父进程中返回子进程的进程号。失败则返回 -1,失败原因存于 errno
中。
注意:子进程的信息是复制而来,而不是与父进程共享。在子进程中修改变量不会影响父进程。
getpid
1 |
|
取得当前进程的进程号。
返回值
当前进程的进程标识符。
getppid
1 |
|
取得当前进程的父进程号。
返回值
当前进程的父进程标识符。
kill
1 |
|
向指定的进程发送给定的信号。
pid
指定要接收信号的进程。
pid > 0
代表将信号传给进程识别码为pid
的进程;pid = 0
代表将信号传给和目前进程相同进程组的所有进程;pid = -1
代表将信号广播传送给系统内所有的进程;pid < 0
代表将信号传给进程组识别码为pid
绝对值的所有进程。
sig
要发送的信号值。
常用信号如下表:
信号值 | 信号名称 | 说明 |
---|---|---|
1 | SIGHUP |
表示用户终端连接(正常或非正常)结束。该信号让进程立即关闭。如果进程是守护进程,一般将重新读取配置文件之后重启。 |
2 | SIGINT |
程序中止信号,用于中止前台进程。相当于按下 Ctrl+C 快捷键。 |
8 | SIGFPE |
在发生致命的算术运算错误时发出。包括浮点运算错误,溢出及除数为 0 等所有的算术运算错误。 |
9 | SIGKILL |
用来立即结束程序的运行。本信号不能被阻塞、处理和忽略,一般用于强制中止进程。 |
14 | SIGALRM |
时钟定时信号,alarm 函数使用该信号。 |
15 | SIGTERM |
正常结束进程的信号,kill 命令的默认信号。如果进程已经发生了问题,那么这个信号是无法正常中止进程的,需要使用 SIGKILL 信号。 |
18 | SIGCONT |
该信号可以让暂停的进程恢复执行。本信号不能被阻断。 |
19 | SIGSTOP |
该信号可以暂停前台进程,相当于按下 Ctrl+Z 快捷键。本信号不能被阻断。 |
这些信号均被定义为宏,直接使用信号名称即可。
返回值
执行成功则返回 0,如果有错误则返回 -1,失败原因存于 errno
中。
signal
1 |
|
为给定的信号设置处理函数。
signum
要处理的信号值。
handler
一个函数指针,指定收到信号时的回调函数。
该参数也可以取以下值:
SIG_IGN
: 表示忽略指定的信号;SIG_DFL
: 表示恢复对信号的默认处理。
示例:
1 |
|
此后程序收到 SIGINT
信号后将转到 signal_handler_fun
函数。
返回值
返回先前的信号处理函数指针,如果有错误则返回 SIG_ERR
(-1)。
sleep
1 |
|
让进程暂停执行一段时间,直到到达指定的时长或是被信号中断。
seconds
要暂停的时长,单位是秒。
返回值
执行成功返回 0,失败则返回剩余秒数。
wait
1 |
|
暂停目前进程执行,等待一个子进程中断或结束。
status
存储子进程状态的地址。
可以使用以下宏取得一些信息:WIFEXITED(status)
: 如果子进程正常结束则为真(非零值)。WEXITSTATUS(status)
: 取得子进程返回的结束代码。建议先判断 WIFEXITED(status)
。WIFSIGNALED(status)
: 如果子进程因为信号结束则为真(非零值)。WTERMSIG(status)
: 取得导致子进程结束的信号代码。建议先判断 WIFSIGNALED(status)
。WIFSTOPPED(status)
: 如果子进程处于暂停执行状态则为真(非零值)。一般只有使用了 WUNTRACED
时才会有此状况。WSTOPSIG(status)
: 取得引发子进程暂停的信号代码。
返回值
成功则返回子进程的进程号,失败则返回 -1,失败原因存于 errno
中。
waitpid
1 |
|
暂停目前进程执行,等待指定子进程中断或结束。
pid
子进程的进程号。
status
存储子进程状态的地址。
options
等待选项。可以是 0 或以下宏的按位或:WNOHANG
: 如果子进程未终止则立即返回,不予等待。WUNTRACED
: 如果子进程进入暂停状态则立即返回,但对终止状态不予理会。
返回值
成功则返回子进程的进程号,失败则返回 -1,失败原因存于 errno
中。