• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

中的std ::线程使用无限循环来增加和显示的值

c/c++ 来源:Fureeish 3次浏览

考虑下面的简单代码:中的std ::线程使用无限循环来增加和显示的值

using ms = std::chrono::milliseconds; 
int val = 0; 
for(;;) 
{ 
    std::cout << val++ << ' '; 
    std::this_thread::sleep_for(ms(200)); 
} 

我们看到,我们无限打印随后的数字每次0.2秒。

现在,我想使用助手类和多线程实现相同的逻辑。我的目标是能够运行类似这样:

int main() 
{ 
    Foo f; 
    std::thread t1(&Foo::inc, f); 
    std::thread t2(&Foo::dis, f); 
    t1.join(); 
    t2.join(); 
} 

Foo::inc()其中将由1Foo::dis()递增对象f的成员变量val将显示相同变量。

由于最初的想法包括递增和打印无限的价值,我会假设这两个函数都必须包含一个无限循环。可能发生的问题是数据竞争 – 读取和增加相同的变量。为了防止我决定使用std::mutex

我实现Foo的思路如下:

class Foo { 
    int val; 
public: 
    Foo() : val{0} {} 
    void inc() 
    { 
     for(;;){ 
      mtx.lock(); 
      ++val; 
      mtx.unlock(); 
     } 
    } 
    void dis() 
    { 
     using ms = std::chrono::milliseconds; 
     for(;;){ 
      mtx.lock(); 
      std::cout << val << ' '; 
      std::this_thread::sleep_for(ms(200)); 
      mtx.unlock(); 
     } 
    } 
}; 

显然,这是缺少mtx对象,所以行

std::mutex mtx; 

的正下方#include书面,宣布mtx作为全球变量。

据我了解,这个类的定义与上述main()功能应该发出两个,独立,无限循环,每个将首先锁定互斥体,无论是增量或显示val和解锁互斥体结合所以其他人可以执行第二个动作

实际发生的并不是显示0 1 2 3 4...的顺序,它只是显示0 0 0 0 0...。我的猜测是我错误地使用了std::mutex::lockstd::mutex::unlock,或者我对多线程的基本理解缺乏一些基本知识。

问题是 – 我的逻辑错在哪里?

  • 如何将接近使用辅助类和两个std::thread s的同一对象的成员函数这个问题?

  • 是否有保证0123’的增量和它的打印将分别使用这种逻辑来一个接一个地发生?即在val在显示之前增加两次,否则永远不会出现这种情况,反之亦然?


===========解决方案如下:

当启动一个成员函数一个线程,你需要通过对象的地址,而不是对象本身

std::thread t2(&Foo::dis, &f); 

请注意,这仍然无法打印1 2 3 4 ..你需要有增量操作和打印替代方案。

#include <thread> 
#include<iostream> 
#include <mutex> 
std::mutex mtx1, mtx2; 

class Foo { 
    int val; 
public: 
    Foo() : val{0} { mtx2.lock(); } 
    void inc() 
    { 
     for(;;){ 
      mtx1.lock(); 
      ++val; 
      mtx2.unlock(); 
     } 
    } 
    void dis() 
    { 
     using ms = std::chrono::milliseconds; 
     for(;;){ 
      mtx2.lock(); 
      std::cout << val <<std::endl; 
      std::this_thread::sleep_for(ms(200)); 
      mtx1.unlock(); 
     } 
    } 
}; 

int main() 
{ 
    Foo f; 
    std::thread t1(&Foo::inc, &f); 
    std::thread t2(&Foo::dis, &f); 
    t1.join(); 
    t2.join(); 
} 

而且看看http://en.cppreference.com/w/cpp/thread/condition_variable


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)