线程池和线程池版本的服务器代码 Linux网络通信( 四 )

_q;int_max_thread;pthread_mutex_t _mutex;pthread_cond_t_cond;};这里我们单独写一个头文件——Task.hpp,其中有任务类,任务类里面有三个成员变量 , 也就是端口号 , IP和套接字,其中有一个成员方法——Run,里面封装了一个Service函数,也就是前面写的,把它放在Task.hpp这个头文件下 , 线程池里面的线程执行run函数即可,头文件内容如下:
#pragma once#include <iostream>#include <unistd.h>static void Service(std::string ip, int port, int sock){while (1){char buf[256];ssize_t size = read(sock, buf, sizeof(buf)-1);if (size > 0){// 正常读取size字节的数据buf[size] = 0;std::cout << "[" << ip << "]:[" << port<< "]# "<< buf << std::endl;std::string msg = "server get!-> ";msg += buf;write(sock, msg.c_str(), msg.size());}else if (size == 0){// 对端关闭std::cout << "[" << ip << "]:[" << port<< "]# close" << std::endl;break;}else{// 出错std::cerr << sock << "read error" << std::endl;break;}}close(sock);std::cout << "service done" << std::endl;}struct Task{int _port;std::string _ip;int _sock;Task(int port, std::string ip, int sock):_port(port),_ip(ip),_sock(sock){}void Run(){Service(_ip, _port, _sock);}};服务器类的核心代码如下:
void loop(){struct sockaddr_in peer;// 获取远端端口号和ip信息socklen_t len = sizeof(peer);_tp = new ThreadPool(THREAD_NUM);_tp->ThreadPoolInit();while (1){// 获取链接// sock 是进行通信的一个套接字_listen_sock 是进行监听获取链接的一个套接字int sock = accept(_listen_sock, (struct sockaddr*)&peer, &len);if (sock < 0){std::cout << "accept fail, continue accept" << std::endl;continue;}int peerPort = ntohs(peer.sin_port);std::string peerIp = inet_ntoa(peer.sin_addr);std::cout << "get a new link, [" << peerIp << "]:[" << peerPort<< "]"<< std::endl;Task* task = new Task(peerPort, peerIp, sock);_tp->Put(task);}}注意几点变化:

  1. 服务器类增加一个线程池成员变量 , 初始化函数里面增加线程池创建(在堆上申请)
  2. 析构函数增加释放线程池资源一步
  3. loop函数中只需要封装任务,并把任务丢进线程池中即可

推荐阅读