【问题标题】:Some simple C code I can't make sense of - What is the mutex doing here?一些我无法理解的简单 C 代码 - 互斥锁在这里做什么?
【发布时间】:2011-02-08 10:01:22
【问题描述】:

抱歉,刚刚在这里找到了这段代码 - 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 );
}

【问题讨论】:

    标签: c mutex


    【解决方案1】:

    如果您没有设置互斥锁,可能会发生以下情况:

    // 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
    

    【讨论】:

    • 这是一种可能的情况,但另一种情况是counter 的最终值为 1,而不是预期的 2。您最终可能会显示两次“计数器值:1”。
    • 是的。 C语言没有定义++操作是否是原子的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-07-31
        • 1970-01-01
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多