多进程并发编程----基于高级的预先创建进程池(accept使用线程上锁)的模型

来源:互联网 发布:新浪微博怎么做淘宝客 编辑:程序博客网 时间:2024/05/16 20:29

本博文介绍如何使用线程对accept进程加锁保护。

使用线程对accept加锁,不仅适用于同一进程内各线程之间的上锁,同样适用于不同进程之间的上锁。

实现要点:

1 互斥变量必须存放在所有进程共享的内存区域内

2 告知线程函数库这是不同进程之间共享的互斥锁


服务端程序的代码如下:

#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <time.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <pthread.h>#include <sys/mman.h>#define BUFFLEN 1024#define SERVER_PORT 8888#define BACKLOG 5#define PIDNUMB 5000pthread_mutex_t *mutex;/* actual mutex will be in shared memory */void my_lock_init(void){pthread_mutexattr_t mutexattr;int fd=open("/dev/zero",O_RDWR,0);if(fd==-1)printf("open err :%s\n",strerror(errno));mutex=mmap(NULL,sizeof(pthread_mutex_t),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);close(fd);pthread_mutexattr_init(&mutexattr);pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);pthread_mutex_init(mutex,&mutexattr);}void my_lock_wait(){pthread_mutex_lock(mutex);}void my_lock_release(){pthread_mutex_unlock(mutex);}static void handle_connect(int s_s,int pid){int s_c;/*客户端套接字文件描述符*/struct sockaddr_in from;/*客户端地址*/int len = sizeof(from);int count=0;/*主处理过程*/while(1){printf("count[%d],pid[%d]\n",count,getpid());/*接收客户端连接*/my_lock_wait();//add write locks_c = accept(s_s, (struct sockaddr*)&from, &len);my_lock_release();//release write lockif(s_c > 0)count++;time_t now;/*时间*/char buff[BUFFLEN];/*收发数据缓冲区*/int n = 0;memset(buff, 0, BUFFLEN);/*清零*/n = recv(s_c, buff, BUFFLEN,0);/*接收发送方数据*/if(n > 0 && !strncmp(buff, "TIME", 4))/*判断是否合法接收数据*/{memset(buff, 0, BUFFLEN);/*清零*/now = time(NULL);/*当前时间*/sprintf(buff, "%24s\r\n",ctime(&now));/*将时间拷贝入缓冲区*/send(s_c, buff, strlen(buff),0);/*发送数据*/sleep(1);}/*关闭客户端*/close(s_c);}}void sig_int(int num){exit(1);}int main(int argc, char *argv[]){int s_s;/*服务器套接字文件描述符*/struct sockaddr_in local;/*本地地址*/signal(SIGINT,sig_int);/*建立TCP套接字*/s_s = socket(AF_INET, SOCK_STREAM, 0);int optval=1;int ret=setsockopt(s_s,SOL_SOCKET,SO_REUSEADDR,(int *)&optval,sizeof(optval));/*初始化地址接哦股*/memset(&local, 0, sizeof(local));/*清零*/local.sin_family = AF_INET;/*AF_INET协议族*/local.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/local.sin_port = htons(SERVER_PORT);/*服务器端口*//*将套接字文件描述符绑定到本地地址和端口*/int err = bind(s_s, (struct sockaddr*)&local, sizeof(local));err = listen(s_s, BACKLOG);/*侦听*///init the write lockmy_lock_init();/*处理客户端连接*/pid_t pid[PIDNUMB];int i =0;for(i=0;i<PIDNUMB;i++){pid[i] = fork();if(pid[i] == 0)/*子进程*/{//printf("pid[%d]\n",getpid());handle_connect(s_s,getpid());}}while(1);close(s_s);return 0;}



1 0
原创粉丝点击