c - 互斥锁和pthread_join的区别

标签 c multithreading pthreads

两者有什么区别?

它们不是一样的吗,因为它们都在等待一个线程完成后再执行另一个线程?

我试图理解下面的代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

main()
{
    int rc1, rc2;
    pthread_t thread1, thread2;

 /*Create independent threads each of which will execute functionC */

     if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc1);
   }

   if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc2);
   }

   /* Wait till threads are complete before main continues. Unless we  */
   /* wait we run the risk of executing an exit which will terminate   */
   /* the process and all threads before the threads have completed.   */

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   exit(0);
}    
void *functionC()
{
   pthread_mutex_lock( &mutex1 );
   counter++;
   printf("Counter value: %d\n",counter);
   pthread_mutex_unlock( &mutex1 );
}

谢谢。

最佳答案

它们实际上不是一回事。

互斥量(互斥信号量)是一种将资源的使用一次限制为一个线程的方法(显然两个线程都可以运行)。当一个线程从 pthread_mutex_lock 调用成功返回时,它保证是唯一持有该锁的线程。在该点之后尝试锁定该互斥量的任何线程通常必须等到拥有线程将其解锁。

换句话说,拥有锁的线程是唯一能够操纵受该锁保护的资源的线程(当然,假设其他线程在未先获取锁的情况下不接触资源 - 你必须玩遵守规则)。

另一方面,pthread_join 允许一个线程等待另一个线程退出。这通常在主线程中用于等待所有子线程退出(还有其他用途,这只是一个典型的用途)。 pthread_join 成功返回意味着另一个线程不再运行。

在您展示的代码中,两个线程同时运行并且 counter 增量和对 printf 的调用都受 mutex1main 末尾的 pthread_join 调用将使主线程等到您的两个子线程退出后再继续。

顺便说一句,您应该检查 pthread_mutex_lock 的返回值,因为它可能失败。在这种情况下,您不想继续修改 protected 资源,因为可能会发生损坏。 pthread_join 也是如此。

而且,为了更全面的测试,下面的函数会更好:

void *functionC() {
    int i;
    for (i = 1000; i > 0; i--) {
        pthread_mutex_lock (&mutex1);
        counter++;
        printf ("Counter value: %d\n", counter);
        pthread_mutex_unlock (&mutex1);
    }
}

因为它更有可能让线程并排运行。如果没有循环,一个线程很有可能会在第二个线程开始之前退出。

关于c - 互斥锁和pthread_join的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6053421/

相关文章:

c++ - 错误 : invalid conversion from ‘int (*)(void*)’ to ‘void* (*)(void*)’

c - Pthread I/O 缓冲区 : Why doese it print a redundant line?

c - 在 C 中使用 ODE 时 undefined symbol

c - 在 C 中,将可变函数指针转换为具有有限参数的函数指针是否安全?

c# - 使表格在函数C#中可用

java - 在Java中重写进程类

Python线程化多个bash子进程?

c - 如何更改Intel icc编译器的缓存写入策略

c - 按位 : different behaviour with negative input value

c++ - LD_PRELOAD 和线程局部变量