Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的多线程:是否需要将未使用的线程设置为NULL?_C_Multithreading - Fatal编程技术网

C中的多线程:是否需要将未使用的线程设置为NULL?

C中的多线程:是否需要将未使用的线程设置为NULL?,c,multithreading,C,Multithreading,这是C中的线程服务器代码。我的问题是:我们需要将未使用的线程设置为NULL吗?在java中,我们需要将thread设置为NULL,以便让它返回到线程池 我对Martin Broadhurst的源代码进行了更改(请参见灰色文本作为注释) /* *线程服务器 *马丁·布罗德赫斯特(www.martinbroadhurst.com) *使用-pthread编译 */ #包括 #include/*memset()*/ #包括 #包括 #include由于C没有对象,因此没有表示线程的对象,因此没有设置为

这是C中的线程服务器代码。我的问题是:我们需要将未使用的线程设置为NULL吗?在java中,我们需要将thread设置为NULL,以便让它返回到线程池

我对Martin Broadhurst的源代码进行了更改(请参见灰色文本作为注释)

/*
*线程服务器
*马丁·布罗德赫斯特(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;
    }