Linux C Posix信号同步父子进程write()写文件异常排查
代码错误说明
这段代码的信号使用、进程逻辑、IO操作都存在错误,叠加后导致最终文件只写入了第一个字符1,具体错误如下:
- 没有为SIGUSR1信号注册自定义处理函数。Linux系统默认对SIGUSR1的处理动作是直接终止进程。父进程写完第一个数字
1后,向子进程发送SIGUSR1唤醒子进程,子进程此时正阻塞在pause()等待信号,收到信号后直接被系统杀死,根本不会执行后续的写入、回发信号逻辑;父进程发送完信号就阻塞在pause()等子进程的信号,子进程已经退出永远不会发信号,程序直接卡在这里,文件里只留了第一次写入的1。 - 子进程发信号的目标PID写错了。
fork()的返回规则是:给子进程返回0,给父进程返回子进程的PID。因此子进程代码块里的pid变量值是0,调用kill(pid, SIGUSR1)实际是执行kill(0, SIGUSR1),语义是向当前进程组所有进程广播信号,根本不是发给父进程,就算信号处理函数注册了,也做不到两个进程点对点同步。 - 写入逻辑本身有多处硬伤:
- 存数字的字符数组
c只开了2字节空间,一旦要写的数字大于等于10,sprintf会写入「两位数字+字符串结束符\0」共3个字节,直接冲爆缓冲区,触发未定义行为。 - 写入长度固定用
sizeof(c)也就是2字节,会把字符串结束符\0也写到txt文件里,不可能得到连续的纯数字序列。 - 数字生成逻辑完全不对:父子进程各自维护循环变量
i,父进程写i、子进程写i+1,不仅会出现数字重复的问题,当n是奇数时最后一个数字根本不会有进程写入,不符合“依次写入1到n”的要求。
- 存数字的字符数组
- 没有满足写入位置要求,也没做基础入参校验:题目要求从文件起始位置依次写入,但父子进程共享文件描述符的当前偏移量,第一次写完后偏移量已经后移,后续写入不会自动回到开头;另外代码直接读取
argv[1]转整数,如果用户运行时没传参数,会直接访问非法内存导致崩溃。
内容的提问来源于stack exchange,提问作者mattiadanisi
相关产品推荐
相关产品推荐

