首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >条件变量POSIX线程: C/C++

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

Stack Overflow用户
提问于 2013-05-15 07:50:57
回答 3查看 1.8K关注 0票数 0

我在学多线程。关于……

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

代码语言:javascript
运行
复制
#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);
    }
}

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

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

我对流动控制的理解是

1)创建线程1、2,并通过thread1控制(考虑单核处理器系统)

2)当在pthread_cond_wait( &condition_var, &count_mutex );例程void *functionCount1()中遇到void *functionCount1()时,它释放锁并等待状态将控制权传递给thread2 void *functionCount1()

3)在thread2中,对变量count进行检查,并且由于它满足count < COUNT_HALT1 || count > COUNT_HALT2 -它指示thread1并重新启动是增加count

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

5)对于count 4-7,thread2正在运行,thread1thread2之间没有交换

6)再次对count 8-10进行steps 2-3重复。

我想知道我的理解是否正确?thread1去睡觉了,thread2唤醒了它(即线程被切换)到count value 1-3 and 8-10 i.e switching between threads happen 5 times了吗?

编辑

我要问这个问题的主要问题是,当thread1遇到pthread_cond_wait( &condition_var, &count_mutex );时,它是否会进入sleep状态,并且不会再次成为active,除非由thread2发出信号,然后才会增加count,也就是说,它不会一次递增1-3,而是每一次增量,它必须等待来自thread2的信号,然后才能进一步进行。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-15 08:07:08

1)线程被创建。控件不传递给thread1,而是由系统调度程序决定执行哪个线程。两个线程都处于活动状态,都应该接收处理器时间,但顺序尚未确定。可能有几个上下文开关,您并不真正控制这一点。

2)正确,thread1进入等待状态,thread2继续工作。同样,控件没有显式传递。

3)是的,thread2会通知条件变量,因此thread1会唤醒并尝试重新获取互斥对象。控件不会立即转到thread1。

一般来说,您应该理解不能真正控制要执行哪个线程;它是系统调度程序的任务,它可以随意放置多少个上下文切换。

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

票数 1
EN

Stack Overflow用户

发布于 2013-05-15 08:56:49

第一:从布滕霍夫那里得到这本书,然后学习它。您引用的页面在几个地方都是不正确的,而且作者显然不理解线程本身。

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

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

第三,pthread_cond_wait中的线程可能会被伪造地唤醒。pthread_cond_wait处于循环中是一个绝对规则,它检查您实际等待的任何条件。也许是这样:

代码语言:javascript
运行
复制
while ( count > COUNT_HALT1 && count < COUNT_HALT2 ) {
    pthread_cond_wait( &condition_var, &count_mutex );
}

最后,有时,在没有互斥保护的部分访问count。这是未定义的行为;必须保护对count的所有访问。在您的情况下,锁定和解锁应该在程序循环之外,两个线程都应该等待条件变量。(但这显然是一种人为的情况--实际上,几乎总是会有一个生产者线程和一个消费者线程。)

票数 3
EN

Stack Overflow用户

发布于 2013-05-15 08:06:05

在理想的世界里,是的,但在实践中,并不完全是这样。

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

thread2获得控制权时,它很可能会在没有停止的情况下结束。不管你有多少CPU。原因是它没有无条件的yield空间。发布mutex并不意味着any1可以锁定它。这是你代码中的第二个赛车条件。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16559583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档