我正在寻找一个使用pthread_join
演示死锁的简单示例;然而,这并非无足轻重。
我从这开始:
void* joinit(void* tid)
{
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
pthread_join(thread2, NULL);
return 0;
}
但是,它说'EINVAL' (无效参数),因为在调用thread2
的{{1}}时尚未指定pthread_create
。
有什么想法吗?
答案 0 :(得分:2)
如果您只想证明pthread_join
可能导致死锁,您可以执行类似以下代码的操作:
#include <stdio.h>
#include <pthread.h>
void* joinit(void* tid)
{
printf("In %#x, waiting on %#x\n", pthread_self(), (*((pthread_t*)tid)));
pthread_join((*((pthread_t*)tid)), NULL);
printf("Leaving %#x\n", pthread_self());
return NULL;
}
int main(void)
{
pthread_t thread1 = pthread_self();
pthread_t thread2;
pthread_create(&thread2, NULL, joinit, &thread1);
joinit(&thread2);
return 0;
}
这将导致主线程在生成的线程上等待,并且生成的线程在主线程上等待(导致保证死锁),而不需要额外的锁定原语来混淆你想要演示的内容。
更直接地回答您的一些问题:
它显示'EINVAL'(无效参数),因为在调用
thread2
的{{1}}时尚未指定pthread_create
。
......并从你的一条评论中......
我试过这个并且它有效,但问题是,它只能起作用,因为有时候我会再次获得EINVAL。
在你的代码中,你连续调用thread1
来产生2个线程:
pthread_create
在pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
代码中,您获取传入的线程句柄以加入:
joinit
这个有时的工作原理和其他你得到pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
的原因与分配给每个线程的上下文time slices的sequencing有关。调用第一个EINVAL
后,pthread_create
返回后会有thread1
的有效句柄,但thread2
的句柄无效,至少直到第二个pthread_create
叫做。
为此,当创建一个线程时,即使返回的线程句柄有效,线程的“活动”行为(即实际运行的线程函数)也可能需要一些额外的时间。在这些情况下,一个线程有可能执行比“预期”更多的代码。在你的代码中,两个pthread_create
函数可能恰好在为主线程分配的时间片中被调用,可以为每个生成的线程提供足够的“时间”在点击允许pthread_join
指向有效句柄的tid_c
语句之前;在EINVAL
案例中,调用了pthread_create(&thread1, NULL, joinit, &thread2)
,并且 pthread_join(*tid_c, NULL)
生成后的线程点击了pthread_create(&thread2, NULL, joinit, &thread1)
,可以为thread2
提供有效句柄(导致错误)。
如果你想保持你的代码与现在的代码类似,你需要添加某种锁以确保线程不会退出或过早地调用任何东西:
#include <stdio.h>
#include <pthread.h>
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* joinit(void* tid)
{
/* this can be above the lock because it will be valid after lock is acquired */
pthread_t* tid_c = (pthread_t*)tid;
int retval = -1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf("%#x waiting on %#x\n", pthread_self(), *tid_c);
retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/* get the lock in the main thread FIRST */
pthread_mutex_lock(&lock);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
/* by this point, both handles are "joinable", so unlock */
pthread_mutex_unlock(&lock);
/* can wait on either thread, but must wait on one so main thread doesn't exit */
pthread_join(thread2, NULL);
return 0;
}
希望这可以提供帮助。
答案 1 :(得分:0)
您的错误的主要原因是,由于height
中.bashrc
的调用,您有两个线程,每个线程等待同一个线程终止。另一个问题是你不能确保每个线程正确地看到另一个线程的ID。
修复如下:
pthread_join