Unix C语言编写基于多线程的小型并发服务器
2018-03-07 16:54
423 查看
转自:https://my.oschina.net/zzw922cn/blog/493896
线程介绍
线程就是运行在一个进程上下文中的逻辑流,一般来说,程序是由每个进程中的单一线程来组成的。但是,我们实际上也可以编写一个进程里同时运行多个线程的程序,线程是由内核调度的,从进程间通信角度来看,一个给定进程内的所有线程共享同样的全局变量。每个线程具有独立的线程上下文,包括一个唯一的整数线程ID,栈,栈指针,程序计数器,通用目的寄存器和条件码。所有运行在一个进程中的线程共享该进程的整个虚拟地址空间。基于线程的逻辑流结合了基于进程和基于IO多路复用的流的特性,同进程一样,线程有内核自动调度,并且内核通过一个整数ID来识别线程,同基于多路IO复用一样,多个线程运行在单一进程的上下文之中,因此共享整个进程的虚拟地址空间,包括代码、数据、堆和共享库以及打开的文件。线程的生命周期
每个进程一开始都是由单一主线程构成的,在某一时刻,主线程创建一个对等线程,从这个时间点开始,两个线程就开始并发地运行。最后,因为主线程执行一个慢速系统调用,例如read函数或者sleep函数,线程就会被内核挂起,控制就会通过上下文切换传递到对等线程。对等线程就这样交替执行,以此类推。 并发服务器代码实现//本程序是基于多线程的并发服务器 //为了避免赋值语句在accept之后才完成的,那么对等线程中的局部变量connfd就得到下一次连接的描述符值,不幸的是,两个线程在同一个描述符上执行输入和输出 //为了避免这种致命竞争,必须将每个accept返回的已连接符分配到它自己的动态分配的存储器块 #include "csapp.h" void echo(int connfd) { int n; char buf[MAXLINE]; rio_t rio; rio_readinitb(&rio,connfd); //带缓冲的读取函数 while((n=rio_readlineb(&rio,buf,MAXLINE))>0) { //向连接符写入内容 printf("server received %d bytes \n",n); rio_writen(connfd,buf,n); } } void *thread(void *vargp); //线程函数声明 //主函数入口 int main(int argc,char **argv) { int listenfd,*connfd,port; //监听描述符,连接符,端口号 socklen_t clientlen=sizeof(struct sockaddr_in); //客户端地址长度 struct sockaddr_in clientaddr; //新建客户端地址 pthread_t tid; //线程id if(argc!=2) { fprintf(stderr,"usage :%s <port>\n",argv[0]); //提示执行格式 exit(0); //正常退出主程序,主进程 } port=atoi(argv[1]); //把端口号转成整型 listenfd=open_listenfd(port); //打开监听端口号 while(1) { //无限循环,等待接受请求 connfd=malloc(sizeof(int)); //动态分配内存给连接描述符,这是为了避免两个线程在同一个描述符上输入输出,导致两个线程在同一个描述符上的不正当竞争 *connfd=accept(listenfd,(SA *)&clientaddr,&clientlen); //接受请求,已连接描述符 pthread_create(&tid,NULL,thread,connfd); //新建线程,并且传递参数connfdp进入线程 } } void *thread(void *vargp) { int connfd=*((int *)vargp);//接受参数 pthread_detach(pthread_self()); //分离线程,使得它不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放 free(vargp); //释放参数存储空间 echo(connfd); //回应客户端 close(connfd); //关闭已连接描述符,这里不用在主线程中关闭,因为线程共享同一虚拟地址空间,此处关闭即可 return NULL;//线程结束 }上面的多线程编译时,要加上-pthread参数,程序运行如下:
zzw@zzw-ThinkPad-Edge-E430c:~$ telnet localhost 9999 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. hello hello
zzw@zzw-ThinkPad-Edge-E430c:~/doc_main/CProgram/Concurrency$ ./echoservert.o 9999 server received 7 bytes
相关文章推荐
- 基于TCP协议用多线程实现并发服务器,实现思路、算法和demo
- lesson6 基于多线程的tcp并发服务器
- 利用多线程编写多个客户端向服务器并发数据
- 并发服务器--02(基于多线程)
- Linux下基于http的小型web服务器编写
- 基于tcp的小型服务器(多线程多进程)
- 常见多线程与并发服务器设计方案举例
- 基于express中间件 搭建小型服务器(随笔)
- TCP并发服务器(七)——可动态增减的线程池,主线程accept——基于UNP代码修改
- Linux网络编程 基于tcp的多线程的服务器
- 基于事件的NIO多线程服务器
- Linux下C编写基本的多线程socket服务器
- Linux网络编程——tcp并发服务器(多线程)
- 网络编程中设计并发服务器,使用多进程与多线程有什么区别?
- java并发多线程-基于线程池设计的ScheduledExecutor任务调度(8)
- 基于HTTP、NIO、单线程实现浏览器并发非阻塞访问服务器文件
- 单进程多线程并发服务器实现
- 多线程与并发服务器设计(23-1)
- 高性能、高并发TCP服务器(多线程调用libevent)
- Websocket全讲解。跨平台的通讯协议 !!基于websocket的高并发即时通讯服务器开发。