linux-是否存在无效的pthread_t ID?
我想为给定的线程ID调用pthread_join,但前提是该线程已经启动。 安全的解决方案可能是添加一个变量以跟踪哪个线程在何处启动。 但是,我不知道是否可以检查pthread_t变量,类似于以下代码。
pthread_t thr1 = some_invalid_value; //0 ?
pthread_t thr2 = some_invalid_value;
/* thread 1 and 2 are strated or not depending on various condition */
....
/* cleanup */
if(thr1 != some_invalid_value)
pthread_join(&thr1);
if(thr2 != some_invalid_value)
pthread_join(&thr2);
其中some_invalid_value可以为0,或者取决于实现的“ PTHREAD_INVALID_ID”宏
PS:我的假设是pthread_t类型是可比较且可分配的,假设基于
PPS:我想这样做,因为我认为在无效的线程ID上调用pthread_join是不确定的行为。 它不是。 但是,加入先前加入的线程是未定义的行为。 现在,假设上面的“函数”被重复调用。无条件调用pthread_join并检查结果可能会导致在先前加入的线程上调用pthread_join。
shodanex asked 2020-01-28T23:33:10Z
6个解决方案
17 votes
一开始您的假设是不正确的。 pthread_t对象是不透明的。 您不能直接在C中比较pthread_t类型。您应该改用pthread_equal。
另一个考虑因素是,如果pthread_create失败,则pthread_t的内容将是未定义的。 可能不再将其设置为无效值。
我的首选是保留pthread_create调用的返回值(以及线程ID),并使用该值来确定每个线程是否正确启动。
qbert220 answered 2020-01-28T23:33:41Z
11 votes
根据Tony的建议,在这种情况下,您可以使用pthread_self。
但是请勿使用==或!=比较pthread_selfs。请使用pthread_self。
从pthread_self手册页中:
因此,无法使用C等式运算符(==)来比较pthread_t类型的变量; 使用pthread_equal(3)代替。
Mat answered 2020-01-28T23:34:14Z
1 votes
不幸的是,在pthread_t是指针的系统上,即使两个arg引用了不同的线程(例如 一个线程可以退出,并且可以使用相同的pthread_t指针值创建一个新线程。
HavePoopWillStep answered 2020-01-28T23:34:34Z
1 votes
我最近遇到了同样的问题。 如果pthread_create()失败,我最终会在phtread_t结构中存储一个未定义的无效值。 结果,如果成功将pthread_create()设置为true,我将与每个线程关联一个布尔值。
然后,我需要做的就是:
void* status;
if (my_thread_running) {
pthread_join(thread, &status);
my_thread_running = false;
}
It'sPete answered 2020-01-28T23:34:59Z
0 votes
我真的希望这是一个很好的问题,希望在C ++类和代码测试中得到更多讨论。
对于某些系统来说,一个选择(可能对您来说有点过头了,但对我来说派上了用场)是启动一个线程,该线程除了有效地等待拆卸信号外什么都不做,然后退出。 该线程在应用程序的生命周期内保持运行状态,在关闭顺序中非常晚地关闭。 在此之前,对于大多数目的,该线程的ID可以有效地用作“无效线程”值,或者更有可能用作“未初始化的”标记。 例如,我的调试库通常跟踪锁定互斥锁的线程。 这要求将跟踪值初始化为合理的值。 因为POSIX愚蠢地拒绝要求平台定义INVALID_THREAD_ID,并且因为我的库允许main()锁定事物(使得pthread_self检查是一个很好的解决方案,所以pthread_create无法用于锁定跟踪),所以这就是我要使用的解决方案 。 它可以在任何平台上运行。
但是请注意,如果您希望能够将静态线程引用初始化为无效值,则需要做更多的设计工作。
breakpoint answered 2020-01-28T23:35:30Z
0 votes
我正在将一些使用pthreads的代码移植到C ++应用程序中,并且我有同样的问题。 我决定更轻松地切换到C ++ 2723224777107440440对象,该对象具有pthread_create方法来决定是否加入,即
if (t.joinable()) t.join();
我发现仅在错误的pthread_t值上调用2723224777107440440(由于pthread_create失败)会导致段错误,而不仅仅是错误返回值。
Mark Lakata answered 2020-01-28T23:35:55Z