Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C pthread_连接死锁的简单示例_C_Multithreading_Pthreads_Deadlock_Pthread Join - Fatal编程技术网

C pthread_连接死锁的简单示例

C pthread_连接死锁的简单示例,c,multithreading,pthreads,deadlock,pthread-join,C,Multithreading,Pthreads,Deadlock,Pthread Join,我正在寻找一个非常简单的示例来演示使用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 ma

我正在寻找一个非常简单的示例来演示使用
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”(无效参数),因为在调用
thread1
pthread\u create
时,尚未指定
thread2


有什么想法吗?

如果您只是想证明
pthread\u 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;
}
joinit
代码中,抓取传入的线程句柄以加入:

pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
这有时起作用,而其他情况下你会得到
EINVAL
的原因与分配给每个线程的上下文和上下文有关。当调用第一个
pthread_create
时,返回后将有一个有效的
thread1
句柄,但
thread2
句柄尚未有效,至少在调用第二个
pthread_create
之前是如此

为此,当创建线程时,即使返回的线程句柄有效,线程变为“活动”的行为(即线程函数实际运行)也可能需要一些额外的时间。在这些情况下,一个线程可能会执行比“预期”更多的代码。在您的代码中,两个
pthread\u create
函数可能恰好在分配给主线程的时间片中被调用,这可以在点击
pthread\u join
语句之前为每个生成的线程提供足够的“时间”,从而允许
tid\u c
指向有效句柄;在
EINVAL
案例中,调用了
pthread\u create(&thread1,NULL,joinit和thread2)
,生成的线程在
pthread\u join(*tid\u c,NULL)
之前命中
pthread\u 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;
}
#包括
#包括
静态pthread\u mutex\u t lock=pthread\u mutex\u初始值设定项;
void*joinit(void*tid)
{
/*这可以在锁的上方,因为在获取锁后它将是有效的*/
pthread_t*tid_c=(pthread_t*)tid;
int-retval=-1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf(“%#x等待%#x\n”,pthread#u self(),*tid#c);
retval=pthread_join(*tid_c,NULL);
printf(“在joint中:tid=%d,retval=%d\n”,*tid_c,retval);
返回NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/*首先在主线程中获取锁*/
pthread_mutex_lock(&lock);
pthread_创建(&thread1、NULL、joinit和&thread2);
pthread_create(&thread2、NULL、joinit和&thread1);
/*至此,两个控制柄都是“可接合”的,因此解锁*/
pthread_mutex_unlock(&lock);
/*可以在任一线程上等待,但必须在其中一个线程上等待,以便主线程不会退出*/
pthread_join(thread2,NULL);
返回0;
}

希望这能有所帮助。

如果您只是想证明
pthread\u 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;
}
joinit
代码中,抓取传入的线程句柄以加入:

pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
这有时起作用,而其他情况下你会得到
EINVAL
的原因与分配给每个线程的上下文和上下文有关。当调用第一个
pthread_create
时,返回后将有一个有效的
thread1
句柄,但
thread2
句柄尚未有效,至少在调用第二个
pthread_create
之前是如此

为此,当创建线程时,即使返回的线程句柄有效,线程变为“活动”的行为(即线程函数实际运行)也可能需要一些额外的时间。在这些情况下,一个线程可能会执行比“预期”更多的代码。在您的代码中,两个
pthread\u create
函数可能恰好在分配给主线程的时间片中被调用,这可以在点击
pthread\u join
语句之前为每个生成的线程提供足够的“时间”,从而允许
tid\u c
指向有效句柄;在
EINVAL
案例中,调用了
pthread\u create(&thread1,NULL,joinit和thread2)
,生成的线程在
pthread\u join(*tid\u c,NULL)
之前命中
pthread\u 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;
}
#包括
#包括
静态pthread\u mutex\u t lock=pthread\u mutex\u初始值设定项;
void*joinit(void*tid)
{
/*这可以在锁的上方,因为在获取锁后它将是有效的*/
pthread_t*tid_c=(pthread_t*)tid;
int-retval=-1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf(“%#x等待%#x\n”,pthread#u self(),*tid#c);
retval=pthread_join(*tid_c,NULL);
printf(“在joint中:tid=%d,retval=%d\n”,*tid_c,retval);
返回NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/*首先在主线程中获取锁*/
pthread_mutex_lock(&lock);
pthread_创建(&thread1、NULL、joinit和&thread2);
pthread_create(&thread2、NULL、joinit和&thread1);
/*至此,两个控制柄都是“可接合”的,因此解锁*/
pthread_mutex_unlock(&lock);
/*可以在任一线程上等待,但必须在其中一个线程上等待,以便主线程不会退出*/
pthread_join(thread2,NULL);
返回0;
}

希望这能有所帮助。

出现错误的主要原因是,由于调用了
pthread\u jo,您有两个线程在等待同一个线程终止