我正在学习线程编程。在执行以下示例时,我遇到了未定义的行为。
static void* print_thread_attr (void* param)
{
pthread_attr_t attr;
int detach_state = PTHREAD_CREATE_JOINABLE;
pthread_getattr_np (pthread_self(), &attr);
pthread_attr_getdetachstate (&attr, &detach_state);
pthread_attr_destroy (&attr);
printf("Detach state of thread [%u] pid [%d] is %s\n", pthread_self(), getpid(),
(PTHREAD_CREATE_JOINABLE == detach_state)?
"JOINABLE THREAD":"DETACHED THREAD");
return NULL;
}
void test_thread_attributes ()
{
pthread_t thread_id1;
pthread_t thread_id2;
pthread_attr_t attr;
printf("main pid [%d]\n", getpid());
pthread_attr_init (&attr);
pthread_create (&thread_id1, &attr, print_thread_attr, NULL);
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
pthread_create (&thread_id2, &attr, print_thread_attr, NULL);
pthread_attr_destroy (&attr);
pthread_join (thread_id1, NULL);
//sleep (1);
}
1.有时,它会打印:
main pid [3394]
Detach state of thread [88292160] pid [3394] is DETACHED THREAD
Detach state of thread [75705152] pid [3394] is JOINABLE THREAD
但有时
main pid [3403] Detach state of thread [75705152] pid [3403] is JOINABLE THREAD Detach state of thread [88292160] pid [3403] is DETACHED THREAD Detach state of thread [88292160] pid [3403] is DETACHED THREAD
这很奇怪,因为我只使用了 2 次 pthread_create,但第二种情况打印了 3 次。在使用valgrind检查时,第一种情况没有内存泄漏,但对于第二种情况,“可能丢失:1个 block 中的136字节”
我需要知道为什么在第二种情况下,线程 88292160 打印两次? 此外,您可能会注意到注释掉的 sleep (1)。当我 sleep 时 (1),我没有观察到第二种情况发生。
最佳答案
调用 pthread_attr_init() 后出现未定义行为两次和第二次在一个已经初始化的对象上:
Calling pthread_attr_init() on a thread attributes object that has already been initialized results in undefined behavior.
对象 attr
被销毁后可以重用:
Once a thread attributes object has been destroyed, it can be reinitialized using pthread_attr_init(). Any other use of a destroyed thread attributes object has undefined results.
但是,您的代码中无法保证该属性会在第二个线程重新初始化之前被第一个线程销毁。因此,您可以使用两个不同的属性对象,甚至可以重复使用相同的属性(无需重新初始化)。但是,由于您在线程中销毁了该属性,因此该选项在您的代码中是不可能的。
最新POSIX standard但是,删除了用于重新初始化已初始化但已销毁的属性和状态的引用未定义行为:
If an implementation detects that the value specified by the attr argument to pthread_attr_init() refers to an already initialized thread attributes object, it is recommended that the function should fail and report an [EBUSY] error.
我假设您的实现使用了一些旧版本并导致未定义的行为。无论如何,这是一个问题,您应该检查 pthread 函数的返回值是否有错误。
看到的重复输出的实际问题是由于实现 issue with the stdio这在 an answer 中有解释。在这里可以解释为什么 sleep
似乎可以“解决”问题以及避免此问题的可能解决方法。
关于c - 执行的线程多于创建的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30096816/