为c+中的螺纹提供临界截面+; 在这个C++程序中,我创建了10个互相竞争的线程来获取临界区。这意味着我使用条件变量作为代码。这个程序中的调度器一次只允许一个线程进入临界区,但是存在一个微妙的问题。当dispatcher授权线程进入时,它会将ready_pipe变量设置为true。如果此时出现一个新线程(在用户设置就绪\u pipe=flase之前),新线程将在未经许可的情况下穿过关键部分 #include <iostream> #include <string> #include <thread> #include <mutex> #include <condition_variable> using namespace std; std::condition_variable con_var_pipe; bool ready_pipe = false; std::mutex pipe_mutex; bool critical_section_is_free=true; void dispatcher() { while(true) { if(critical_section_is_free) { critical_section_is_free=false; // send signal to a thread to enter critical section std::lock_guard<std::mutex> lk(pipe_mutex); ready_pipe = true; con_var_pipe.notify_one(); } } } void consumer() { std::unique_lock<std::mutex> lk(pipe_mutex); /* The Problem is Here at below line.When a new thread comes, it will pass through this block because it see ready_pipe is true!!!*/ con_var_pipe.wait(lk, [] {return ready_pipe;}); /// critical section starts ready_pipe=false; /// here accessing pipe is occurring . /// critical section ends critical_section_is_free=true; } int main() { std::thread allThreads[10]; for(int i = 0 ; i<10 ; i++) { allThreads[i]=std::thread(consumer); } thread disp(dispatcher); for(int i = 0 ; i< 6 ; i++) { allThreads[i].join(); } disp.join(); return 0; } #包括 #包括 #包括 #包括 #包括 使用名称空间std; std::条件变量控制变量管道; bool ready_pipe=false; std::mutex pipe\u mutex; 布尔临界截面为自由=真; void调度程序() { while(true) { 如果(关键部分空闲) { 临界截面为无=假; //向线程发送信号以进入临界段 std::锁定保护lk(管道互斥); ready_pipe=true; con_var_pipe.通知_one(); } } } 无效消费者() { std::unique_lock lk(管道互斥); /*问题就在下面。当一个新线程出现时, 它将通过此块,因为它看到ready_管道是真实的*/ con_var_pipe.wait(lk,[{return ready_pipe;}); ///临界段开始 就绪管道=错误; ///在这里,访问管道正在发生。 ///临界截面端部 临界截面为自由=真; } int main() { std::线程所有线程[10]; 对于(inti=0;i

为c+中的螺纹提供临界截面+; 在这个C++程序中,我创建了10个互相竞争的线程来获取临界区。这意味着我使用条件变量作为代码。这个程序中的调度器一次只允许一个线程进入临界区,但是存在一个微妙的问题。当dispatcher授权线程进入时,它会将ready_pipe变量设置为true。如果此时出现一个新线程(在用户设置就绪\u pipe=flase之前),新线程将在未经许可的情况下穿过关键部分 #include <iostream> #include <string> #include <thread> #include <mutex> #include <condition_variable> using namespace std; std::condition_variable con_var_pipe; bool ready_pipe = false; std::mutex pipe_mutex; bool critical_section_is_free=true; void dispatcher() { while(true) { if(critical_section_is_free) { critical_section_is_free=false; // send signal to a thread to enter critical section std::lock_guard<std::mutex> lk(pipe_mutex); ready_pipe = true; con_var_pipe.notify_one(); } } } void consumer() { std::unique_lock<std::mutex> lk(pipe_mutex); /* The Problem is Here at below line.When a new thread comes, it will pass through this block because it see ready_pipe is true!!!*/ con_var_pipe.wait(lk, [] {return ready_pipe;}); /// critical section starts ready_pipe=false; /// here accessing pipe is occurring . /// critical section ends critical_section_is_free=true; } int main() { std::thread allThreads[10]; for(int i = 0 ; i<10 ; i++) { allThreads[i]=std::thread(consumer); } thread disp(dispatcher); for(int i = 0 ; i< 6 ; i++) { allThreads[i].join(); } disp.join(); return 0; } #包括 #包括 #包括 #包括 #包括 使用名称空间std; std::条件变量控制变量管道; bool ready_pipe=false; std::mutex pipe\u mutex; 布尔临界截面为自由=真; void调度程序() { while(true) { 如果(关键部分空闲) { 临界截面为无=假; //向线程发送信号以进入临界段 std::锁定保护lk(管道互斥); ready_pipe=true; con_var_pipe.通知_one(); } } } 无效消费者() { std::unique_lock lk(管道互斥); /*问题就在下面。当一个新线程出现时, 它将通过此块,因为它看到ready_管道是真实的*/ con_var_pipe.wait(lk,[{return ready_pipe;}); ///临界段开始 就绪管道=错误; ///在这里,访问管道正在发生。 ///临界截面端部 临界截面为自由=真; } int main() { std::线程所有线程[10]; 对于(inti=0;i,c++,multithreading,mutex,C++,Multithreading,Mutex,,只需使用两个计数器和一个布尔值即可实现基本的“取一个数”方案 一个计数器,released\u thread,指示哪个线程可以继续。这在逻辑上等同于“now service”指示符 另一个,即next\u,指示下一个等待的线程。这在逻辑上等同于将采用的下一个数字 布尔值指示线程是否允许继续以及何时结束,以便执行人员知道何时调用下一个数字 算法如下: 等待: 拿到锁 记下next\u变量的值并递增 广播(通知所有)条件变量 等待条件变量,直到布尔值为真且released_thread计数器等于步

,只需使用两个计数器和一个布尔值即可实现基本的“取一个数”方案

一个计数器,
released\u thread
,指示哪个线程可以继续。这在逻辑上等同于“now service”指示符

另一个,即
next\u
,指示下一个等待的线程。这在逻辑上等同于将采用的下一个数字

布尔值指示线程是否允许继续以及何时结束,以便执行人员知道何时调用下一个数字

算法如下:

等待:

  • 拿到锁

  • 记下
    next\u
    变量的值并递增

  • 广播(通知所有)条件变量

  • 等待条件变量,直到布尔值为真且
    released_thread
    计数器等于步骤2中记录的值

  • 松开锁

  • 完成后,获取锁,将布尔值设置为false,广播条件变量,然后释放锁

  • 高管人员

  • 拿到锁

  • 等待条件变量,直到布尔值为false且
    next\u
    不等于
    released\u thread

  • 增量
    released\u thread
    并将布尔值设置为true

  • 广播条件变量

  • 转至步骤2


  • 这里实际上没有任何问题。您对所讨论的更改有什么问题?您需要什么帮助?@DavidSchwartz先生,当一个新线程到达wait()时,如果see ready_pipe==true,它可以通过关键部分。但一次只能通过一个线程(哪个调度员已经批准并设置了ready_pipe=true)。对。那么你的问题是什么?你需要一个算法吗?如果需要,问一个。你需要实现吗?如果需要,描述你需要实现的算法。不可能知道你需要什么帮助。@DavidSchwartz我需要修改我的代码(或任何建议)为了避免注意到的问题。对,我明白了。那么是什么阻止了你进行这些修改?你不知道什么?你在坚持什么?你找到你想要使用的算法了吗?如果没有,请寻求帮助。如果是,请描述它们并寻求帮助实现它们。你已经陈述了一个问题,但没有提出具体的要求谢谢,先生。这正是我想要的。使用两个整数是一个非常好的方法。您可能更喜欢使用两个条件变量,一个用于释放服务员,另一个用于通知主管任务已完成。别忘了广播服务员条件变量(全部通知)是的,当然。再次非常感谢。我知道Stack社区为您感到骄傲,先生