我一直在使用pthread
库创建&在C中加入线程。
我应该何时从一开始就创建一个脱离的线程?与可连接的线程相比,它是否提供任何性能优势?
在可连接(默认情况下)线程上不执行pthread_join()
是否合法?或者这样的线程是否应该在detach()
之前使用pthread_exit()
函数?
答案 0 :(得分:72)
当您知道不想使用pthread_join()
等待它时,创建一个分离的线程。唯一的性能优势是,当分离的线程终止时,可以立即释放其资源,而不必等待线程在可以释放资源之前加入。
加入可连接线程是“合法的”;但通常不建议这样做,因为(如前所述)在连接线程之前不会释放资源,因此如果你不加入它们,它们将无限期地保持捆绑(直到程序退出)。
答案 1 :(得分:1)
什么时候应该从一开始就创建一个独立的线程?
无论何时应用程序不关心该线程何时完成,也不关心其线程的返回值,(线程可以通过pthread_exit
将值传送回其他线程/应用程序)。 / p>
例如,在客户端服务器应用程序模型中,服务器可以创建一个新线程来处理每个请求。但是服务器本身并不关心线程的线程返回值。在这种情况下,创建分离的线程是有意义的。
服务器唯一需要确保的是当前已处理的请求已完成。它可以做到这一点,只需退出主线程而不退出整个程序/应用程序即可。当进程中的最后一个线程退出时,应用程序将自然退出。
伪代码可能类似于:
@mixin absoluteCenterVertical($extraTransformVals: noExtraValues) {
@if $extraTransformVals == noExtraValues {
transform: translateY(-50%);
} @else {
transform: translateY(-50%) $extraTransformVals;
}
}
另一个示例可能是守护程序或记录器线程,该线程会在应用程序运行期间定期记录一些信息。
与可连接线程相比,它具有任何性能优势吗?
在性能方面,可连接线程与分离线程之间没有区别。唯一的区别是,对于分离的线程,其资源(例如线程堆栈和任何关联的堆内存,等等-那些“资源”的确切构成是特定于实现的)。
在可连接(默认情况下)线程上不执行pthread_join()是否合法?
是的,不加入线程是合法的。 /* 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);
}
是一个便捷功能,除非您需要,否则无需使用。但是请注意,默认情况下,创建的线程是 joinable 线程。
您可能想加入的一个示例是线程执行在它们之间分配的“一部分”工作。在这种情况下,您需要在继续操作之前检查所有线程是否完成。 Task farm parallelism是一个很好的例子。
还是这样的线程应该在pthread_exit()之前始终使用detach()函数?
不是必需的。但是,您通常需要在创建时决定要使用 joinable 还是 detached 线程。
请注意,虽然可以通过调用pthread_attr_setdetachstate
来设置属性pthread_join
来创建可分离线程,但线程决定可以决定在任何时间点自行分离。与pthread_detach(pthread_self())
。另外,具有另一个线程的线程ID(PTHREAD_CREATE_DETACHED
)的线程可以与pthread_t
分离。