繁体   English   中英

条件变量POSIX线程:C / C ++

[英]Condition Variable POSIX Thread : C/C++

我正在学习多线程。 关于至于对于有关

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SCHEDULING

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


pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;



void *functionCount1();
void *functionCount2();

int  count = 0;

#define COUNT_DONE  10
#define COUNT_HALT1  3
#define COUNT_HALT2  6



main()
{
   pthread_t thread1, thread2;
   pthread_create( &thread1, NULL, &functionCount1, NULL);
   pthread_create( &thread2, NULL, &functionCount2, NULL);



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

   printf("Final count: %d\n",count);

   exit(0);
}



// Write numbers 1-3 and 8-10 as permitted by functionCount2()

void *functionCount1()
{
   for(;;)
   {
      // Lock mutex and then wait for signal to relase mutex
      pthread_mutex_lock( &count_mutex );



      // Wait while functionCount2() operates on count
      // mutex unlocked if condition varialbe in functionCount2() signaled.

      pthread_cond_wait( &condition_var, &count_mutex );

      count++;

      printf("Counter value functionCount1: %d\n",count);
      pthread_mutex_unlock( &count_mutex );

      if(count >= COUNT_DONE) return(NULL);
    }
}



// Write numbers 4-7



void *functionCount2()
{
   for(;;)
    {
       pthread_mutex_lock( &count_mutex );

       if( count < COUNT_HALT1 || count > COUNT_HALT2 )
       {
          // Condition of if statement has been met.
          // Signal to free waiting thread by freeing the mutex.
          // Note: functionCount1() is now permitted to modify "count".

          pthread_cond_signal( &condition_var );
       }
       else
       {
          count++;
          printf("Counter value functionCount2: %d\n",count);
       }



       pthread_mutex_unlock( &count_mutex );

       if(count >= COUNT_DONE) return(NULL);
    }
}

我想知道代码的控制流程。

作为pthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled

我对流量控制的了解是

1)创建线程一,二,并将线程1传递给控件(考虑单核处理器系统)

2)遇到pthread_cond_wait( &condition_var, &count_mutex ); thread1例程void *functionCount1() -释放锁定并进入等待状态,将控制权传递给thread2 void *functionCount1()

3)在thread2中检查变量count ,因为它满足count < COUNT_HALT1 || count > COUNT_HALT2 count < COUNT_HALT1 || count > COUNT_HALT2它向thread1发出信号并重新启动以增加count

4)重复Steps 2 to 3thread1 1-3显示1-3

5)对于count 4-7 ,线程2处于活动状态,并且thread1thread2之间没有切换

6)对于count 8-10再次重复steps 2-3

我想知道我的理解是否正确? 是否thread1进入睡眠状态和thread2将其唤醒(即线程切换)的count value 1-3 and 8-10 ie switching between threads happen 5 times

编辑

我主要要问的问题是,知道thread1在遇到pthread_cond_wait( &condition_var, &count_mutex );时是否会进入sleep状态pthread_cond_wait( &condition_var, &count_mutex ); 除非thread2发出信号,否则它将不会再次active ,只有这样递增count即它不会thread2增加1-3 ,而是每次增加,它必须等待thread2发出的信号才可以继续进行

首先:取得Butenhof的书,然后进行研究。 您引用的页面在很多地方都是错误的,并且作者显然不了解自己的线程。

关于您的问题:首先要说的是您不知道代码的控制流程。 这是线程的特征,在现代处理器上,您经常会发现线程实际上是并行运行的,一个内核执行一个线程,另一个内核执行另一个线程。 并且在每个线程内,处理器可能会以意外方式重新安排内存访问。 例如,这就是为什么需要互斥锁的原因。 (您提到“考虑单核处理系统”,但实际上,单核通用系统已不存在。)

其次,线程的调度方式取决于操作系统。 例如,在您的代码中, functionCount2可以一直运行到functionCount1开始之前的完成为止,这意味着functionCount1将永远等待。

第三, pthread_cond_wait的线程可能会虚假地唤醒。 绝对规则是pthread_cond_wait处于循环中,该循环检查您实际上正在等待的条件。 也许像:

while ( count > COUNT_HALT1 && count < COUNT_HALT2 ) {
    pthread_cond_wait( &condition_var, &count_mutex );
}

最后,有时,您正在访问不受互斥锁保护的部分中的count 这是未定义的行为; 所有 count访问都必须受到保护。 在您的情况下,锁定和解锁可能应该在程序循环之外,并且两个线程都应等待条件变量。 (但这显然是人为的情况,在实践中,几乎总是有生产者线程和消费者线程。)

在理想世界中,是的,但实际上却并非如此。

您无法预测哪个胎面首先要控制。 是的,它可能是thread1 ,但仍不能保证。 这是代码中的第一个赛车条件。

thread2控制thread2 ,很可能它将完成而不会停止。 无论您有多少个CPU。 原因是它没有地方无条件 yield 您释放mutex的事实并不意味着any1可以锁定它。 它是您代码中的第二种赛车条件。

因此, thread1将打印11 ,这是唯一保证的部分。

1)创建线程。 控制权不传递给线程1,而是系统调度程序来决定执行哪个线程。 两个线程均处于活动状态,都应接收处理器时间,但是顺序不确定。 可能会有多个上下文切换,您并没有真正控制它。

2)正确,线程1进入等待状态,线程2继续工作。 同样,控制未明确传​​递。

3)是的,线程2通知条件变量,因此线程1将苏醒并尝试重新获取互斥量。 控件不会立即转到线程1。

通常,您应该了解您无法真正控制要执行的线程。 这是系统调度程序的工作,系统调度程序可以根据需要放置尽可能多的上下文切换。

UPD:使用条件变量,您可以控制多线程环境中任务的执行顺序。 因此,我认为您的理解或多或少是正确的:线程1正在等待条件变量以获取来自线程2的信号。 接收到信号后,thread1继续执行(在重新获取互斥量之后)。 但是在线程之间切换-可能有许多线程,其中5只是理论上的最小值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM