C中的多线程:是否需要将未使用的线程设置为NULL?
这是C中的线程服务器代码。我的问题是:我们需要将未使用的线程设置为NULL吗?在java中,我们需要将thread设置为NULL,以便让它返回到线程池 我对Martin Broadhurst的源代码进行了更改(请参见灰色文本作为注释)C中的多线程:是否需要将未使用的线程设置为NULL?,c,multithreading,C,Multithreading,这是C中的线程服务器代码。我的问题是:我们需要将未使用的线程设置为NULL吗?在java中,我们需要将thread设置为NULL,以便让它返回到线程池 我对Martin Broadhurst的源代码进行了更改(请参见灰色文本作为注释) /* *线程服务器 *马丁·布罗德赫斯特(www.martinbroadhurst.com) *使用-pthread编译 */ #包括 #include/*memset()*/ #包括 #包括 #include由于C没有对象,因此没有表示线程的对象,因此没有设置为
/*
*线程服务器
*马丁·布罗德赫斯特(www.martinbroadhurst.com)
*使用-pthread编译
*/
#包括
#include/*memset()*/
#包括
#包括
#include由于C没有对象,因此没有表示线程的对象,因此没有设置为NULL的内容。分离的线程在终止时将消失。未连接的线程在连接时会消失。由于C没有对象,因此没有表示线程的对象,因此没有设置为NULL的内容。分离的线程在终止时将消失。一个未连接的线程在被连接时会消失。不。好吧,还不是100%清楚你在想什么样的Java构造(我打赌你可以调用一个close方法,而不是将它设置为null并让GC处理),但这是不相关的,因为
pthread\u t
是一个整数(可能)类型,而不是指针,因此不能设置为NULL
C不是垃圾收集的,因此即使它是一个指针,线程也无法知道或关心您是否将其设置为null
POSIX线程不使用线程池。pthread\u create
函数实际上创建了一个全新的OS级线程,从处理程序返回的线程实际上会退出它。(其实不是。它仍然挂起,直到您调用pthread_join,因为您没有将其创建为分离线程。)
您应该做的是将线程创建为分离线程,因为您的代码现在正在泄漏可连接线程
另外,使用&newsock作为参数是危险的,因为它在主循环的每次迭代中都会被破坏和重新创建。这是一种可能在作者的测试中从未出现过的争用条件,因为在轻负载下,主线程将等待下一个accept返回,而它是在工作线程上访问的,并且在大多数系统上,相同的空间将被一次又一次地用于变量
您可以使用malloc创建一个存储套接字fd的位置(您需要在处理程序函数结束时释放它),或者,如果您的平台允许(大多数情况下),只需将值转换为指针,然后将其转换回处理程序函数中。否。好吧,还不是100%清楚您所考虑的Java构造是什么(我打赌你可以调用一个close方法,而不是将其设置为null并让GC处理),但这与此无关,因为
pthread\u t
是一个整数(可能)类型,而不是指针,因此不能设置为NULL
C不是垃圾收集的,因此即使它是一个指针,线程也无法知道或关心您是否将其设置为null
POSIX线程不使用线程池。pthread\u create
函数实际上创建了一个全新的OS级线程,并且从处理程序返回的线程实际上会退出它。(当然,不是这样。它仍然挂起,直到您调用pthread\u join,因为您没有将其作为分离线程创建。)
您应该做的是将线程创建为分离线程,因为您的代码现在正在泄漏可连接线程
另外,使用&newsock作为参数是危险的,因为它在主循环的每次迭代中都会被破坏和重新创建。这是一种竞争条件,可能在作者的测试中从未出现过,因为在轻负载下,主线程将等待下一个accept返回,而在工作线程和mos上访问它t系统相同的空间将被反复用于变量
您可以使用malloc创建一个存储套接字fd的位置(您需要在处理程序函数结束时释放该位置),或者,如果您的平台允许,也可以(大多数情况下),只需将值强制转换为指针,然后在处理程序函数中将其强制转换回。您有一个pthread作为线程id,没有对象,并且它的工作方式与java gc不同
以下情况之一时线程终止:
- 它的启动函数返回
- 线程调用pthread_exit()
- 被pthread_cancel()取消
- 进程调用exit()中的任何线程
- 主线程返回,
在这种情况下,进程中的所有线程将立即终止
您有一个pthread\t作为线程id,没有对象,并且它不像java gc那样工作
以下情况之一时线程终止:
- 它的启动函数返回
- 线程调用pthread_exit()
- 被pthread_cancel()取消
- 进程调用exit()中的任何线程
- 主线程返回,
在这种情况下,进程中的所有线程将立即终止
你说得对。&newstock很危险。除此之外,它完全坏了。它需要修复,但对于这样简单的东西(例如newstock是int),我会(void*)newstock并让线程执行int newstock=(long)ptr而不是去malloc。我只会在有控件结构被填充的情况下使用mallocin@CraigEstey我推荐malloc是因为我不知道这样做的能力是否保证是可移植的-你有关于整数到指针和返回的往返转换的POSIX参考吗?它总是有效的,即使是对于脑残的MS compi使用LP32/LLP64模型的LER。所有Unix系统都使用LP32/LP64。对于32位,这是没有意义的。以下是参考/标准,在90年代正式化,它甚至可以在LLP64上工作,因为我们只需要较低的32位。为简洁起见,我可以做int-newsock=(int)ptr;而且,我是一个参考人,因为我在30多年的时间里已经多次这样做了。你可以在指针中隐藏一个int——检查table@CraigEstey只是大小不能说明什么
/*
* 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;
}