多进程并发编程----基于高级的预先创建进程池(accept使用线程上锁)的模型
2016-04-25 17:56
716 查看
本博文介绍如何使用线程对accept进程加锁保护。
使用线程对accept加锁,不仅适用于同一进程内各线程之间的上锁,同样适用于不同进程之间的上锁。
实现要点:
1 互斥变量必须存放在所有进程共享的内存区域内
2 告知线程函数库这是不同进程之间共享的互斥锁
服务端程序的代码如下:
使用线程对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 5000 pthread_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 lock s_c = accept(s_s, (struct sockaddr*)&from, &len); my_lock_release();//release write lock if(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 lock my_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; }
相关文章推荐
- JAVA多线程与并发学习总结
- 详解C#中通过委托来实现回调函数功能的方法
- php要解决的问题
- 序列化必须灭亡!
- python_笔记8_生成列表,列表表达式
- JAVA验证身份证格式及合法性
- 实现手机重启代码
- 如何解决PHP里大量数据循环时内存耗尽的问题
- Java序列化、反序列化
- HM编码器代码阅读(25)——和熵编码有关的一些类
- django fields lookup methods
- Java读带有BOM的UTF-8文件乱码原因及解决方法
- 1.4.C语言如何操作内存
- 安卓开发文件缓存方法的具体实现(参考代码)
- 通过 spring 容器内建的 profile 功能实现开发环境、测试环境、生产环境配置自动切换
- 多进程并发编程----基于高级的预先创建进程池(accept使用文件上锁)的模型
- 【C#设计模式-建造者模式】
- 如何在同一台电脑上使用两个github账户
- VB.NET2013 发邮件
- 深入理解Java的接口和抽象类