一些简单的C代码我无法理解 - 互斥体在这里做什么?

时间:2011-02-08 01:53:15

标签: c mutex

很抱歉只是在这里找到了这段代码 - http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html并且使用此代码解释了互斥锁,但它已经过了一些。我理解互斥锁的功能,它在关键部分保护共享变量。这里的具体细节令我困惑!根据我的理解,我们正在使用pthread_create创建一个新线程,它正在运行functionC进程,它会增加一个计数器。计数器是受保护的变量,并且由于两个函数同时运行,如果计数器不受互斥锁保护,则计数器将返回错误的值。

这是正确的/关闭吗?非常感谢:)。

#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 );
}

3 个答案:

答案 0 :(得分:3)

你的解释是完全正确的。如果多个线程同时尝试修改counter,则可能会丢失更新。

答案 1 :(得分:3)

如果你没有使用互斥锁,可能会发生这种情况:

// initialization
counter = 0;

// thread 1 runs:
counter++;

// context switch
// thread 2 runs:
counter++;

// context switch
// thread 1 runs and printf "Counter value: 2"
printf("Counter value: %d\n",counter);

// context switch
// thread 2 runs and printf "Counter value: 2"
printf("Counter value: %d\n",counter);

所以,你最终可能得到这个输出:

Counter value: 2
Counter value: 2

现在,在互斥锁就位的情况下,确保增量及其打印将以原子方式运行,因此您100%确定输出将是:

Counter value: 1
Counter value: 2

但永远不会:

Counter value: 2
Counter value: 2

答案 2 :(得分:1)

是的,你是对的。互斥锁在尝试递增计数器时阻止线程相互踩踏。

由于递增运算符不一定是原子操作(有关详细信息,请参阅here),从多个线程递增相同的变量可能会导致意外结果。互斥锁通过一次只允许一个线程递增计数器来防止这种情况发生。

最后的join语句只是确保主程序和两个线程都同时退出。否则主程序将退出,线程将被挂起。

相关问题