这是 C 中的线程服务器代码。我的问题是:我们是否需要将未使用的线程设置为 NULL?在java中,我们需要将thread设置为NULL,让它返回线程池。
我对 Martin Broadhurst 的源代码进行了更改(请参阅灰色文本作为评论)
/*
* A threaded server
* by Martin Broadhurst (www.martinbroadhurst.com)
* Compile with -pthread
*/
#include <stdio.h>
#include <string.h> /* memset() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#define PORT "32001" /* Port to listen on */
#define BACKLOG 10 /* Passed to listen() */
void *handle(void *pnewsock)
{
/* send(), recv(), close() */
return NULL;
}
int main(void)
{
int sock;
pthread_t thread;
struct addrinfo hints, *res;
int reuseaddr = 1; /* True */
/* Get the address info */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
return 1;
}
/* Create the socket */
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1) {
perror("socket");
return 1;
}
/* Enable the socket to reuse the address */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1) {
perror("setsockopt");
return 1;
}
/* Bind to the address */
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
perror("bind");
return 0;
}
freeaddrinfo(res);
/* Listen */
if (listen(sock, BACKLOG) == -1) {
perror("listen");
return 0;
}
/* Main loop */
while (1) {
pthread_attr_t *attr; //<===I added this
size_t size = sizeof(struct sockaddr_in);
struct sockaddr_in their_addr;
int * ptr; //<===I added this
ptr = malloc(sizeof(int)); //<===I added this
ptr = accept(sock, (struct sockaddr*)&their_addr, &size);
if (newsock == -1) {
perror("accept");
}
else {
printf("Got a connection from %s on port %d\n",
inet_ntoa(their_addr.sin_addr), htons(their_addr.sin_port));
//I added the following "if" statement
if (pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED) != 0){
fprintf(stderr, "Failed to set thread detached\n");
}
else {
//if (pthread_create(&thread, NULL, handle, &newsock) != 0) {
if (pthread_create(&thread, attr, handle, ptr) != 0 ) {
fprintf(stderr, "Failed to create thread\n");
}
}
}
}
close(sock);
return 0;
}
==========-============== 代码来自这里: http://martinbroadhurst.com/source/threaded-server.c.html
最佳答案
没有。好吧,你不是 100% 清楚你在想什么 Java 构造(我敢打赌你可以调用一个 close 方法而不是将它设置为 null 并让 GC 处理它),但这无关紧要,因为......
pthread_t
是整数(可能)类型,不是指针,因此不能设置为 NULL。- C 不会被垃圾回收,因此即使它是一个指针,线程也无法知道或关心您将它设置为 null。
- POSIX 线程不使用线程池。
pthread_create
函数实际上创建了一个全新的操作系统级线程,从处理程序返回实际上退出了它。 (好吧,不是真的。在您调用 pthread_join 之前它仍然存在,因为您没有将它创建为分离线程。)
您应该做的是将线程创建为分离线程,因为您的代码现在正在泄漏可连接线程。
此外,使用 &newsock 作为参数是危险的,因为它在主循环的每次迭代中都会被销毁并重新创建。这是一个可能从未出现在作者测试中的竞争条件,因为在轻负载下,主线程将等待下一个 accept 返回,同时在工作线程上访问它,并且在大多数系统上将使用相同的空间并结束变量。
您可以使用 malloc 创建一个存储套接字 fd 的位置(您需要在处理程序函数结束时释放它),或者,如果您的平台允许这样做(大多数情况下允许),只需将值转换为一个指针,然后在处理程序函数中将其投回。
关于c - C : do we need to set unused thread to NULL? 中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33116110/