64

我一直在使用该pthread库在 C 中创建和加入线程。

  1. 我什么时候应该从一开始就创建一个分离的线程?与可连接线程相比,它是否提供任何性能优势?

  2. pthread_join()不在可连接(默认)线程上执行 a 是否合法?或者这样的线程应该总是在ingdetach()之前使用该函数吗?pthread_exit()

4

2 回答 2

85
  1. 当你知道你不想用pthread_join(). 唯一的性能优势是,当分离的线程终止时,可以立即释放其资源,而不必等待线程加入才能释放资源。

  2. 不加入可连接线程是“合法的”;但通常不建议这样做,因为(如前所述)在线程加入之前不会释放资源,因此如果您不加入它,它们将无限期地保持绑定(直到程序退出)。

于 2010-09-21T03:04:39.160 回答
4

我什么时候应该从一开始就创建一个分离的线程?

每当应用程序不关心该线程何时完成并且不关心线程的返回值时(线程可以通过 将值传回给其他线程/应用程序pthread_exit)。

例如,在客户端-服务器应用程序模型中,服务器可以创建一个新线程来处理每个请求。但是服务器本身并不关心线程的线程返回值。在这种情况下,创建分离线程是有意义的。

服务器唯一需要确保的是当前处理的请求已经完成。它可以这样做,只需退出主线程而不退出整个程序/应用程序。当进程中的最后一个线程退出时,应用程序/程序自然会退出。

伪代码可能如下所示:

/* A server application */

void process(void *arg)
{
    /* Detach self. */
    pthread_detach(pthread_self());
    
    /* process a client request. */
    
    pthread_exit(NULL);
}

int main(void)
{

    while (not_done) {
        pthread_t t_id;
        errno = pthread_create(&t_id, NULL, process, NULL);
        if (errno) perror("pthread_create:");
    }

    /* There may be pending requests at this point. */
    
    /* Just exit the main thread - not the whole program - so that remaining
       requests that may still be processed can continue. */
    pthread_exit(NULL);
}

另一个示例可能是守护程序或记录器线程,只要应用程序运行,它就会定期记录一些信息。

与可连接线程相比,它是否提供任何性能优势?

在性能方面,可连接线程与分离线程之间没有区别。唯一的区别是,对于分离的线程,它的资源(例如线程堆栈和任何相关的堆内存等等 - 构成这些“资源”的确切内容是特定于实现的)。

不在可连接(默认)线程上执行 pthread_join() 是否合法?

是的,不加入线程是合法的。pthread_join是一个非常方便的功能,除非您需要,否则绝不需要使用。但请注意,默认情况下创建的线程是可连接的线程。

您可能想要加入的一个示例是当线程执行在它们之间拆分的“一块”工作时。在这种情况下,您需要在继续之前检查所有线程是否已完成。任务场并行性就是一个很好的例子。

或者这样的线程应该总是在 pthread_exit() 之前使用 detach() 函数吗?

没有必要。但是您经常想在创建时决定是否需要可连接分离的线程。


PTHREAD_CREATE_DETACHED请注意,虽然可以通过调用设置属性来创建可分离线程pthread_attr_setdetachstate,但线程决定可以决定在任何时间点分离自身,例如使用pthread_detach(pthread_self())。此外,具有pthread_t另一个线程的线程 id () 的线程可以使用pthread_detach(thread_id);.

于 2020-07-18T19:58:08.490 回答