主要是和之前的博文有关,之前在这里有一部分代码是通过创建新的进程来应对新的用户请求的,但是基本没怎么解释怎么用的,所以这里做点小笔记。
首先引入的库:
#include <thread>
这是C++11中自带的。今天的重点是用这个库中的thread
,使用方法大概是这样的:
#include <iostream>
#include <thread>
#include <string>
void sayHello(const std::string& name) {
std::cout << "Hello " << name << std::endl;
}
int main() {
std::string name = "UKnowWho";
std::thread t(sayHello, name);
t.join();
std::cout << "Goodbye" << std::endl;
return 0;
}
// 输出
Hello UKnowWho
Goodbye
可以看到输出如上方所示,简单解释下怎么运行的。join()
函数会使得子线程先运行完之后再接着运行父线程,所以先是打印出了Hello UKnowWho
,然后才打印Goodbye
。如果创建了不止一个子线程,那么就会等所有的子线程完成之后才会继续执行父线程。如果传入的函数是成员函数那么应该这样:
TcpThread *th = new TcpThread();
std::thread sth(&TcpThread::Main, th);
即第一个参数是类成员函数地址(void (Object:😗)(int, double)),第二个是类的对象,然后后面才跟的是函数的参数(如果有的话)。
但是我们之前的代码大概是这样的:
int main(int argc, char *argv[]) {
unsigned short port = 8080;
if (argc > 1) {
port = atoi(argv[1]);
}
XTcp server;
server.CreateSocket();
server.Bind(port);
for (;;)
{
XTcp client = server.Accept();
TcpThread *th = new TcpThread();
th->client = client;
//创建线程
std::thread sth(&TcpThread::Main, th);
//释放父线程拥有的子线程资源
sth.detach();
}
server.Close();
getchar();
return 0;
}
用的是detach
,这个函数会将子线程分离,这样父线程和子线程就会同时进行,各自干各自的。这点恰好符合我们的需求,就是当当前服务器正在为一个客户服务的时候,能够创建新的线程来为新的客户服务。
大概知道这么多就行,如果想更深入了解(例如detach
的注意事项,作用域什么的)可以看下参考的博文。