我一直在使用C语言中的pthread
库创建和加入线程。
什么情况下应该一开始就将线程设置为分离状态?相对于可连接线程,它是否提供任何性能优势?
在默认情况下可连接线程上不执行
pthread_join()
是合法的吗?或者这样的线程是否应该在pthread_exit()
前总是使用detach()
函数?
使用 pthread_join()
时,如果您知道不想等待线程,则创建一个分离线程。其唯一的性能优势是,当一个分离线程终止时,它的资源可以立即释放,而无需等待线程被加入(joined)才能释放资源。
不加入可加入的线程是“合法的”,但通常不建议这样做,因为(如前所述)资源不会在线程被加入之前被释放。如果您不加入线程,它们将无限期地保留(直到程序退出)。
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()函数?
不必要。但通常您希望在创建时决定您想要一个可加入(joinable)还是分离(detached)的线程。
pthread_attr_setdetachstate
并设置属性PTHREAD_CREATE_DETACHED
来创建可分离的线程,但线程可以在任何时候决定自行分离,例如使用pthread_detach(pthread_self())
。另外,具有另一个线程的线程 ID(pthread_t
)的线程可以使用pthread_detach(thread_id);
进行分离。pthread_exit
只会退出该线程,如果还有其他线程在运行,则进程将继续运行。这就是我所说的“退出主线程”的意思。另一方面,从任何线程调用exit
将退出整个进程/应用程序,例如。 - P.P
exit()
、_exit()
或_Exit()
。如果主线程执行pthread_exit()
,则其他线程确实有机会完成。 - Jonathan Leffler