分类: LINUX
2013-05-28 15:31:38
有这么一个需求:使用udp socket通信,其中一个udp服务端口用于接收很多用户(用户数超过端口总数65535)。这些用户需要创建不通客户端源端口用于和另一个服务器通信,并维持着这个客户端socket用于接收服务器的消息。由于是udp socket通信,TCP/IP协议栈不需要维护连接状态,从而想到了udp服务端口用于和客户通信,使用新的线程和另一服务端通信。
背景前提:原来已经存在了一个进程A,可以完成udp服务端口与客户端通信,创建udp客户端端口和另一个udp服务器通信。现在通过一个程序外壳用于提供用户的服务接口,内部通过fork + exec启动进程A的几个副本,这样把原来单一进程所做的事情,分配给多个进程来做,并且进程间无耦合,预计能达到比较理想的效果。用户和进程A副本在壳程序中形成的对应关系{用户唯一标识 + struct sockaddr_in + 分配的进程A副本端口号},通过hash表以用户唯一标识为主键组织,加快查找速度。
调用fork处,进程执行分叉。由于进程组织成树状,父节点可能拥有多个子节点,子节点只有一个父节点,父进程返回子进程的进程id号,子进程返回0。
注:execl最后一个参数为NULL,即execl("/usr/lcal/bin/ls", "-lh", NULL);
char * argvs[] = {"-lh", NULL}
execv一般这么用execv("/usr/local/bin/ls",argvs);
末尾是p的,是只需要给出可执行文件名,会在bash一般搜寻的路径中查找。末尾是e的,可以传递环境变量。
注:fork调用产生后,子进程的进程内存空间完全从父进程内存空间拷贝, 文件描述符等引用系数会增加。
要解决的问题:
1、子进程组中有进程结束,则整个进程组一起结束。
解决:此问题好办,在主进程中捕获SIGCHLD信号,向子进程组中的每一个进程发送一个退出信号。kill(pid, SIGKILL),最后主进程退出即可。
2、父进程结束,则整个子进程组一起结束。不能托孤给init进程
解决:捕获SIGKILL信号,发现系统不给捕获SIGKILL和SIGSTOP的机会。并且存在一个现象是前台启动CTRL+C,则整个进程组都结束。在另一个vty中,kill -9 `pidof processes_manager`则产生了孤儿进程。是否可以利用这一点?
现在探寻一下原因:在一个vty中使用前台启动proceees_manager进程,按下CTRL + C键后,整个进程组一起结束。
在另一个vty中使用kill -9 `pidof processes_manager`,子进程组成了孤儿进程,被托孤给init进程了。
man 7 signal
很明确的提出来:The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored。现在足以证明靠信号是没得搞了,用户发一个SIGKILL信号过来,在信号上无解了。
父进程不能直接处死子进程,那就子进程自杀好了。子进程启动一个定时器,5秒检测一次自己的父进程pid,发现父进程pid是init进程pid时,则自己结束。
顺便写一下信号:
进程在阻塞状态捕获信号后,会立即变成触发状态,errno被置位EINTR。测试代码如下:
点击(此处)折叠或打开