首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

UNIX多进程连服务端出现异常

2012-08-10 
UNIX多进程连服务端出现错误C/C++ codevoid CreateProcess(int start, int end, func f){pid_t pidint cl

UNIX多进程连服务端出现错误

C/C++ code
void CreateProcess(int start, int end, func f){        pid_t pid;        int client = -1;        int loop_times = 0;        int fd = open(ERRLOG, O_CREAT|O_RDWR|O_APPEND);        close(fd);        fd = open(SENDLOG, O_CREAT|O_RDWR|O_APPEND);        close(fd);        fd = open(RECEIVELOG, O_CREAT|O_RDWR|O_APPEND);        close(fd);        struct sigaction old;        struct sigaction new;        new.sa_handler = ChildExit;        new.sa_flags |= SA_RESTART;        sigemptyset(&new.sa_mask);                while(start <= end)        {                pid=fork();                if(pid == 0 || pid == -1)                {                        break;                }                sigaction(SIGCHLD, &new, &old);                usleep(50000);                start++;        }        if(pid == -1)        {                Log(ERRLOG,FormatString("Create process failed:%s", strerror(errno)));                exit(EXIT_FAILURE);        }        if(pid == 0)        {                int client = 0;                while(1)                {                        client = Process(start);                        if(client != 0)                        {                                break;                        }                        loop_times++;                        printf("%d:connect failed.After %d s continue...\n", getpid(), loop_times);                        sleep(loop_times);                        if(loop_times > 100)                        {                                Log(ERRLOG, FormatString("%s:Create socket failed",itoa(getpid()),strerror(errno)));                                exit(EXIT_FAILURE);                        }                }                if(f(client, start))                {                        close(client);                        exit(EXIT_SUCCESS);                }                else                {                        printf("%d:error\n", getpid());                        close(client);                        exit(EXIT_FAILURE);                }        }}void ChildExit(int sig){        pid_t pid;        int status;        while((pid = waitpid(-1 , &status, WNOHANG)) > 0)        {                if(WIFEXITED(status))                {                        if(WEXITSTATUS(status) == EXIT_SUCCESS)                        {                                printf("%d exit success...\n", pid);                        }                        else                        {                                printf("%d exit failed:%d...\n", pid, status);                        }                }                else                {                        printf("%d occur error:%s\n", pid, strerror(errno));                        Log(ERRLOG, FormatString("%s occur error:%s\n", itoa(pid), strerror(errno)));                }        }}int Process(int start){        printf("%d:start\n", getpid());        int client = CreateSocket();        if(!client)        {                return 0;        }        if(!ConnectServer(client))        {                return 0;        }        return client;}int CreateSocket(){        int client = socket(AF_INET, SOCK_STREAM, 0);        if(client == -1)        {                return 0;        }        return client;}int ConnectServer(int client){        struct sockaddr_in servaddr;        socklen_t socklen = sizeof(servaddr);        bzero(&servaddr, sizeof(servaddr));        servaddr.sin_family = AF_INET;        inet_aton(HOST, &servaddr.sin_addr);        servaddr.sin_port = htons(PORT);        if(connect(client, (struct sockaddr *)&servaddr, socklen) == -1)        {                return 0;        }        return 1; }

我创建了多个进程去连接服务端。但是在实际执行中发现当子进程进程数量过多的时候其中某些子进程会收到Interrupted system call然后终止终止。请问通过以上代码能不能看出是那里出问题了。或者有什么原因可能导致出现此问题。有神马解决方法。



[解决办法]
其实这个单进程就足够了, epoll+非阻塞connect, 很快就秒掉了。

假设你非要多进程单线程的模型拉做这个事情, 实在就拿你没办法了... 你这个也就能造成个几千的并发压力, 再高系统也不让你创建那么多进程了.

你应该是进程池的工作模式, 每个子进程不断的请求, 直到总请求次数全部结束.
一看这个需求, 就知道各个进程之间要共享一个计数, 很明显共享内存里面放一个计数就行了, 每个子进程开始请求之前加锁检查一下是否全部完成,还没全部完成就-1,解锁开始请求,否则退出进程,就这么回事.

父进程的做法比较多, 其实就是所有子进程都主动退出了, 那么说明所有的任务都完成了。

所以,父进程阻塞在那里wait就行了,一直到所有子进程退出。

但是,如果想让程序实用一点,也就是打印请求进度,并且支持用户操控信号,那么阻塞wait就不合适了,怎么办? 让父进程轮询,在轮询里加锁检查计数以便打印进度,并且在轮询里waitpid非阻塞回收子进程,一直到所有子进程都退出了,那父进程就可以退出了。

热点排行