cha34.进程组、会话和作业控制
读书笔记
34.1
假设一个父进程执行了下面的步骤。
这个应用程序设计可能会碰到什么问题?考虑 shell 管道。
如何避免此类问题的发生?
1 |
|
- 假设不发送SIGUSER时
- 当不使管道时,可以看到有小于等于10个子进程显示收到
SIGUSER1
- 如果使用管道,会发现
child-%d: %d
被重复输出了多次,这是由于stdout
被重定向后变成了全缓冲,fork的子进程退出后fflush()时会将fork前未flush的数据打印出来。
- 当不使管道时,可以看到有小于等于10个子进程显示收到
- 假设执行该命令
./practice34.1 | cat
,输出会是User defined signal 1
,即cat
与程序同属一个进程组,cat也会收到该信号,导致无法正常执行(非预期内)
避免
记录每个子进程的pid,依次给每个pid发送信号,避免使用killpg或kill时使用负值pid
34.2
编写一个程序来验证父进程能够在子进程执行exec0之前修改子进程的进程组ID
但无法在执行exec0之后修改子进程的进程组ID。
1 | // |
可以看到,在parent_handler
中,对子进程修改pgid后再次查询其pgid,并没有改变
报错为Permission denied
34.3
编写一个程序来验证在进程组首进程中调用setsid会失败
1 |
|
结果
1 | error: Operation not permitted |
34.4
修改程序清单34-4 (disc_SIGHUP.c)来验证当控制进程在收到 SIGHUP 信号而不终止时,内核不会向前台进程组中的成员发送SIGHUP信号。
1 |
|
小结
嗯,确实是这样
- 复习知识
- alarm到期发送SIGALARM,默认行为是结束进程
- getpgrp是获取当前进程的进程组id,getpgid是获得参数pid指定进程的进程组id
- signal函数失败时的返回值是
SIG_ERR
知识补漏
SIGTSTP
和SIGSTOP
- 两个信号的作用都是让进程暂停,区别是
SIGSTOP
不可以捕获。
- 两个信号的作用都是让进程暂停,区别是
wait
和waitpid
wait
当进程停止时返回- waitpid可通过options参数等待停止的子进程
waitflags.h中的部分宏定义
1 | /* Bits in the third argument to `waitpid'. */ |
等待暂停的进程
1 |
|
34.5
假设将程序清单34-6中的信号处理器中解除阻塞SIGTSTP信号的代码移动到处理器的开头部分。这样做会导致何种竞争条件?
可能会导致同时执行多个tstphandler?
34.6
编写一个程序来验证当位于孤儿进程组中的一个进程试图从控制终端调用read时会得到EIO的错误.
1 |
|
嗯,确实是这样
1 | CHECK: error:5(Input/output error), /root/linux/cha34/practice34.6.c:20 |
34.7
编写一个程序来验证当SIGTTIN、SIGTTOU或SIGTSTP三个信号中的一个信号被发送给孤儿进程组中的一个成员时,如果这个信号会停止该进程(即处理方式为SIG_DFL),那么这个信号就会被丢弃(即不产生任何效果),但如果该信号存在处理器,就会发送该信号。
1 | // |
似乎还没成功,输出一直是R(运行中的后台进程组)
1 | /root/linux/practice34.7 e 0 |
可能发现能调用handler就可以了吧?