示例项目

多线程的服务器

服务器赢博体育程序的一个重要目标是能够同时处理多个客户机。实现具有此功能的服务器的最常见方法是使服务器成为多线程的。通过利用线程以及它们同时做多件事的能力,我们可以显著提高服务器赢博体育程序的性能。

在这些笔记中,我将引导您完成将简单的web服务器转换为多线程服务器赢博体育程序所需的步骤。

线程基础

Linux上有几个可用的库来实现线程。其中最简单和最广泛使用的是POSIX线程库,或pthread库。

要在程序中使用POSIX线程,首先要包含适当的头文件:

# include < pthread.h >

除了包含这个头文件之外,我们还需要在为赢博体育程序编译代码的命令行中使用-pthread选项。

在赢博体育程序中实现线程所需的惟一函数是pthread_create()函数,该函数启动运行一个新线程。

下面是一段代码,说明了这个函数是如何工作的:

pthread_t线程;pthread_create(线程、零serveRequest &new_socket);

线程变量是一个线程标识符。如果我们需要在启动线程后与它交互,我们将使用thread变量来访问线程。

pthread_create()中的第三个参数是指向线程函数的指针。thread函数是一个函数,它接受一个参数,一个泛型void*指针,并返回一个void*指针作为结果。当我们启动线程时,线程函数中的代码将开始运行。当我们到达该线程函数代码的末尾时,线程停止运行。

pthread_create()中的第四个参数是指向我们想要传递给线程函数的数据的指针。

螺纹miniweb

在miniweb服务器的线程版本中,我将使用一种常见的模式来设置服务器。这个模式是每个连接一个线程的模式。

服务器通常具有接受新客户端连接的无限循环。在这个版本的服务器端赢博体育程序中,我们将在每次接受连接时启动一个新线程:

当(1){struct sockaddr_in客户端;Int new_socket, c = sizeof(struct sockaddr_in);New_socket = accept(server_socket, (struct sockaddr *) &client, (socklen_t*)&c);如果(new_socket != -1) {pthread_t线程;pthread_create(线程、零serveRequest &new_socket);}}

我还修改了serveRequest()函数的原始形式,使serveRequest()函数作为线程函数工作。

原始的serverrequest()函数采用这种形式

// fd是用于与客户端通信的套接字的文件描述符。从fd读取请求并通过fd发送//响应。}

这个函数的新形式是

void* serverquest (void* pfd) {int fd = *((int*) pfd);//和之前一样使用fd return NULL;}

我们将接收一个泛型void*指针,指向存储文件描述符的int类型,而不是传递一个文件描述符来处理。为了获得文件描述符,我们必须将泛型指针类型强制转换为正确的指针类型,解引用该指针,然后将数据复制到一个局部变量中供我们使用。