线程间通信

时间:2016-03-01 11:07:04

标签: c++ multithreading c++11

以下是我的简单代码,我想在console_task中获取i中变量dialer_task的值,而不使用全局变量。

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <thread>
#include "console.hpp"

using namespace std;

void console_task(){
    console();
}

void dialer_task(){
    int i=0;
    while (1) {
        printf("LOOP %d\n",i);
        i++;
        sleep(5);
    }
}

int main()
{
    thread t1(console_task);
    thread t2(dialer_task);

    t1.join();
    t2.join();
    return 0;
}

1 个答案:

答案 0 :(得分:4)

可能没有全局变量来共享线程之间状态的约束基本上留下了两个可行的替代方案;

  1. 在堆上分配共享状态并将其传递给线程
  2. 在原始线程的堆栈上分配共享状态,并将其“提供”给工作线程以供共享使用。
  3. 两种解决方案的关键是确保访问受到适当保护或原子化。

    一个简单的解决方案是使用std::atomic并在线程之间共享引用。

    #include <type_traits>
    #include <thread>
    #include <atomic>
    #include <iostream>
    
    void console_task(std::atomic_int& j) {
        using namespace std;
    
        int i = 0;
        while (++i < 50) {
            cout << "task " << j << endl; // uncontrolled access to the console (demo)
            std::chrono::microseconds delay{50};
            this_thread::sleep_for(delay);
        }
    }
    
    void dialer_task(std::atomic_int& j){
        using namespace std;
        int i = 0;
        while ( ++i < 10) {
            //cout << "LOOP " << i << endl;  // uncontrolled access to the console (demo)
            std::chrono::microseconds delay{145};
            this_thread::sleep_for(delay);
            j = i;
        }
    }
    
    int main()
    {
        std::atomic_int i { 0 };
        std::thread t1( console_task, std::ref(i));
        // a lambda with reference capture could also be used
        // std::thread t1( [&](){console_task(i);} );
        std::thread t2( dialer_task, std::ref(i));
    
        t1.join();
        t2.join();
        return 0;
    }
    

    共享atomic有一个问题,它需要在线程的持续时间内保持有效(就像在这里一样)。

    Demo code

    可以考虑进一步基于堆的替代方案;例如使用共享std::mutexstd::shared_ptr