C ++中的线程间通信

时间:2018-01-05 11:04:54

标签: c++ multithreading message-queue

从我的程序主要开始,我将启动线程(A和B)。 Thread_A负责生成信号块(它将这些块存储在两个线程可见的矩阵中),而Thread_B负责其传输。

我的目标是每次thread_A生成一个块时,它必须通知thread_B它的传输(可能一个好的方法是发送填充的memmory块的地址)。为此,我想使用POSIX消息队列,但遗憾的是我没有这种东西的经验。

有人能为我提供适用于这种情况的线程间通信的简单示例吗?

1 个答案:

答案 0 :(得分:1)

这里有一些使用条件变量的例子。一个线程生成信号。另一个传输它们。这个例子中的信号只是int。还有一个睡眠模拟一些负载。希望这会有所帮助:

#include <cstdlib>
#include <ctime>

#include <iostream>
#include <future>
#include <thread>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <utility>
#include <chrono>

using namespace std;

bool rdy_flg;
mutex rdy_mtx;
condition_variable rdy_cond_var;

bool finished;

vector<int> my_signals;

void GenerateSignals() {

    const int kNumOfTests = 10;

    for (int i = 0; i < kNumOfTests; ++i) {

        // 1. for each test generate some random signals - just int's in this case
        int n = rand() % 11;
        if (n == 0) n = 5;
        vector<int> vec(n);
        for (int j = 0; j < n; ++j) vec[j] = rand() % 1000;

        {
            // 2. now we are updating the global variable
            // -> need to lock here
            lock_guard<mutex> lg(rdy_mtx);
            my_signals = vec;
            cout  << "Generating signals: ";
            for (auto& v : my_signals) cout << v << " ";
            cout << endl;
            rdy_flg = true;

           // if last test -> set finished to true for other thread
           // to know to not wait for new notifications any more
           if (i == kNumOfTests-1)
              finished = true;



        }  // 3. lock guard goes out of scope -> automatic unlock 

        // 4. send notification to the other thread
        rdy_cond_var.notify_one();



        // 5. simulate some heavy work
        this_thread::sleep_for(chrono::seconds(1));
    }
}

void TransmitSignals() {

    while (!finished) {
        // need unique lock here
        unique_lock<mutex> ul(rdy_mtx);

        // wait for notification until rdy_flg is true - there is something to read
        rdy_cond_var.wait(ul, [] { return rdy_flg; });
        cout << "Transmitting signals: ";
        for (auto& v : my_signals) cout << v << " ";
        cout << endl;

        // reset rdy_flg to false for not to process the same signals again
        rdy_flg = false;
    }
}

int main() {
    srand(time(nullptr));

    auto f1 = async(launch::async, GenerateSignals);
    auto f2 = async(launch::async, TransmitSignals);
}

这是实例:https://wandbox.org/permlink/hgoZB8POiWAYEZ5I

这里是重复处理相同信号的更新示例:

#include <cstdlib>
#include <ctime>

#include <chrono>
#include <condition_variable>
#include <future>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>
#include <vector>

using namespace std;

mutex mtx_signals;
mutex mtx_cout;
bool finished;

vector<int> my_signals;

void GenerateSignals() {
  const int kNumOfTests = 3;

  for (int i = 0; i <= kNumOfTests; ++i) {
    int n = rand() % 11;
    if (n == 0) n = 5;
    vector<int> vec(n);
    for (int j = 0; j < n; ++j) vec[j] = rand() % 1000;

    if (!finished) {
      {
        lock_guard<mutex> lg(mtx_signals);
        my_signals = vec;
        if (i >= kNumOfTests) finished = true;
      }
      if (!finished) {
        lock_guard<mutex> lgcout(mtx_cout);
        cout << "Generating signals: ";
        for (auto& v : my_signals) cout << v << " ";
        cout << endl;
      }
    }

    this_thread::sleep_for(chrono::seconds(1));
  }
}

void TransmitSignals() {
  while (!finished) {
    vector<int> sigs;
    {
      lock_guard<mutex> lg(mtx_signals);
      sigs = my_signals;
    }
    if (sigs.size()) {
      lock_guard<mutex> lgcout(mtx_cout);
      cout << "Transmitting signals: ";
      for (auto& v : sigs) cout << v << " ";
      cout << endl;
    }
    this_thread::sleep_for(chrono::milliseconds(200));
  }
}

int main() {
  srand(time(nullptr));

  auto f1 = async(launch::async, GenerateSignals);
  auto f2 = async(launch::async, TransmitSignals);
}

https://wandbox.org/permlink/R7DdsdItqJX0L07k