thread库介绍:
头文件:
#include
基本API:
//创建一个新线程来执行 run 函数:thread t(run); //实例化一个线程对象t,让该线程执行run函数,构造对象后线程就开始执行了//假如说 run 函数需要传入参数 a 和 b,我们可以这样构造:thread t(run,a,b); //实例化一个线程对象t,让该线程执行run函数,传入a和b作为run的参数//需要注意的是,传入的函数必须是全局函数或者静态函数,不能是类的普通成员函数。//join 函数会阻塞主线程,直到 join 函数的 thread 对象标识的线程执行完毕为止,join 函数使用方法如下:t.join(); //调用join后,主线程会一直阻塞,直到子线程的run函数执行完毕//但有时候我们需要主线程在继续完成其它的任务,而不是一直等待子线程结束,这时候我们可以使用 detach 函数。//detach 函数会让子线程变为分离状态,主线程不会再阻塞等待子线程结束,而是让系统在子线程结束时自动回收资源。使用的方法如下:t.detach();
编程:
#include
g++ -o test_thread test_thread.cpp -lpthread
2.服务端编程server.cpp
#include"server.h"server::server(int port,string ip):server_port(port),server_ip(ip){}server::~server(){ for(auto conn:sock_arr) { close(conn); } close(server_sockfd);}void server::run(){ server_sockfd = socket(AF_INET,SOCK_STREAM, 0); //定义sockaddr_in struct sockaddr_in server_sockaddr; server_sockaddr.sin_family = AF_INET;//TCP/IP协议族 server_sockaddr.sin_port = htons(server_port);//server_port;//端口号 server_sockaddr.sin_addr.s_addr = inet_addr(server_ip.c_str());//ip地址,127.0.0.1是环回地址,相当于本机ip //bind,成功返回0,出错返回-1 if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1) { perror("bind");//输出错误原因 exit(1);//结束程序 } //listen,成功返回0,出错返回-1 if(listen(server_sockfd,20) == -1) { perror("listen");//输出错误原因 exit(1);//结束程序 } //客户端套接字 struct sockaddr_in client_addr; socklen_t length = sizeof(client_addr); //不断取出新连接并创建子线程为其服务 while(1){ int conn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length); if(conn<0) { perror("connect");//输出错误原因 exit(1);//结束程序 } cout<<"文件描述符为"<
server.h
#ifndef SERVER_H#define SERVER_H#include
主程序:
#include"server.h"int main(){ server serv(8023,"127.0.0.1");//创建实例,传入端口号和ip作为构造函数参数 serv.run();//启动服务}
makefile:
test_server: test_server.cpp server.cpp server.hg++ -o test_server test_server.cpp server.cpp -lpthreadclean:rm test_server