以线程实现TCP并发服务器
来源:互联网 发布:java如何取绝对值 编辑:程序博客网 时间:2024/06/05 08:25
对服务器来说,以线程为客户服务的方式有三种:
1.每来一个客户就为其创建一个线程;
2.创建一个线程池,在线程中accept;
3.创建一个线程池,在main中accept;
对于第一种:
int main(int argc, char const *argv[]){int listenfd,connfd;void sig_int(int);void *doit(void *);pthread_t tid;socklen_t clilen,addrlen;struct sockaddr *cliaddr;listenfd = /*创建一个监听套接字*/cliaddr = malloc(addrlen);signal(SIGINT,sig_int);for(;;){connfd = accept(listenfd,cliaddr,&clilen);pthread_create(&tid,NULL,&doit,(void *) connfd);}return 0;}void *doit(void *arg){void web_child(int);pthread_detach(pthread_self());web_child((int) arg);//对套接字进行处理close((int) arg);return NULL:}
对于第二种:
typedef struct {pthread_t thread_tid;long thread_count;}THread;THread *tptr;int listenfd,nthreads;socklen_t addrlen;pthread_mutex_t mlock;int main(int argc, char const *argv[]){int i;void sig_int(int,thread_make(int));listenfd = tcp_listen(/**/);nthreads = atoi(argv[argc-1]);tptr = calloc(nthreads,sizeof(THread));//一共nthreads个线程,线程信息用结构体数组来保存for(i=0;i<nthreads;i++)thread_make(i);//提前创建一个线程池signal(SIGINT,sig_int);for(;;)pause();}void thread_make(int i){void *thread_main(void *);pthread_create(&tptr[i].thread_tid,NULL,&thread_main,(void *) i);return;}void *thread_main(void *arg){ int connfd; void web_child(int); socklen_t clilen; struct sockaddr *cliaddr; cliaddr = malloc(addrlen); for(;;) { clilen = addrlen; /*先抢到锁的线程,先accept,这样保证每次只有一个线程处理新到来的连接; 这里不用互斥锁也是可以的,但是每个线程都会阻塞在accept中,当有一个客户到来时,就会引发惊群问题(所有线程被唤醒,但只有一个线程为客户服务)*/ pthread_mutex_lock(&mlock); connfd = accept(listenfd,cliaddr,&clilen); pthread_mutex_unlock(&mlock); tptr[(int) arg].thread_count++; web_child(connfd); close(connfd); }}
对于第三种:
typedef struct {pthread_t thread_tid;long thread_count;}THread;THread *tptr;#define MAXNCLI 32int clifd[MAXNCLI] ,iget ,iput;pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;static int nthreads;int main(int argc, char const *argv[]){int i;int connfd;socklen_t clilen;struct sockaddr *cliaddr;void sig_int(int,thread_make(int));listenfd = tcp_listen(/**/);nthreads = atoi(argv[argc-1]);cliaddr = malloc(addrlen);tptr = calloc(nthreads,sizeof(THread));//一共nthreads个线程,线程信息用结构体数组来保存 iget=iput=0;for(i=0;i<nthreads;i++)thread_make(i);//提前创建一个线程池signal(SIGINT,sig_int);for(;;){clilen = addrlen;connfd = accept(listenfd,cliaddr,&clilen);//在main里accept,然后把accept返回的套接字保存起来,分配一个线程为其服务pthread_mutex_lock(&clifd_mutex);clifd[iput] = connfd;if(++iput == MAXNCLI)iput = 0;pthread_cond_signal(&clifd_cond);pthread_mutex_unlock(&clifd_mutex);}}void thread_make(int i){void *thread_main(void *);pthread_create(&tptr[i].thread_tid,NULL,&thread_main,(void *) i);return;}void *thread_main(void *arg){ int connfd; void web_child(int); for(;;) { pthread_mutex_lock(&clifd_mutex); while(iget == iput) pthread_cond_wait(&clifd_cond,&clifd_mutex);//进入pthread_cond_wait,就会释放clifd_mutex,返回就重新加锁 connfd = clifd[iget]; if(++iget == MAXNCLI) iget = 0; pthread_mutex_unlock(&clifd_mutex); tptr[(int) arg].thread_count++; web_child(connfd); close(connfd); }}
0 0
- 以线程实现TCP并发服务器
- tcp并发服务器之线程
- 【原创】TCP Socket 简单练习 --- 线程池实现并发服务器
- Linux TCP协议使用线程实现并发服务器
- 线程实现并发服务器
- 线程实现tcp服务器
- TCP多线程并发服务器+线程池+echo
- C 线程实现并发服务器
- Linux网络编程 - TCP Socket 简单练习:线程池实现并发服务器
- Linux C——TCP并发服务器客户端(线程实现)
- 改造-TCP-Java-客户机/服务器应用程序-并发-限制线程上限
- TCP并发服务器
- 并发服务器设计 Tcp/
- TCP并发服务器设计
- TCP并发服务器程序
- TCP并发服务器
- TCP并发服务器
- tcp多线程并发服务器
- Java JDBC 连接Mysql数据库
- 最简单的系统日志收集方式 elk + rsyslog客户端
- 跳台阶
- 《zookeeper》---原生原生API中的watch机制二
- 我有10块钱,可以喝多少瓶汽水
- 以线程实现TCP并发服务器
- java连接redis中的数据查、增、改、删操作的方法
- Rxandroid2.0 使用一
- eclipse关闭讨厌的菜单
- Imageloader使用
- Comparable与Comparator的区别
- 大并发
- 常用vim命令
- c语言指针类问题