同步两个功能

时间:2018-02-12 00:43:47

标签: c++ synchronization

我目前正在尝试同步两个不同的功能来用数字填充向量。一个函数用偶数填充向量,另一个用奇数填充。数字应该在矢量中以正确的顺序插入(结果是:numbers [i] = i)

void incOdd(std::vector<uint8_t> *numbers, TestMutex *inEven, TestMutex *inOdd){

    for(uint8_t i = 1; i < 100;i++){
        if((i + 1) % 2 == 0){
            continue;
        }


        inOdd->lock();
        (*numbers).push_back(i);
        inOdd->unlock();

    }

}

void incEven(std::vector<uint8_t> *numbers, TestMutex *inEven, TestMutex *inOdd){

    for(uint8_t i = 0; i < 100;i++){


        if(i % 2 != 0){
            continue;
        }


        inEven->lock();
        (*numbers).push_back(i);
        inEven->unlock();

    }
}

注意:测试互斥体只是一个类,它是互斥锁的子节点,只定义了锁定和解锁函数。 (锁定函数后面有一个计数器用于测试)

由于这是一项练习任务,因此不得更改参数并仅在括号中起作用。我已经尝试过使用condition_variables让他们互相等待,但它并没有奏效。 我没有其他方法,希望你有解决方案

更新

TEST_CASE("synchronize [thread]") {
    TestMutex inEven;
    TestMutex inOdd;
    inEven.lock();
    std::vector<uint8_t> numbers;

    std::thread even(incEven,&numbers,&inEven,&inOdd);
    std::thread odd(incOdd,&numbers,&inEven,&inOdd);

    odd.join();
    even.join();
    for(size_t i=0; i < numbers.size(); i++) {
        REQUIRE(numbers[i] == (i+1));
    }
    REQUIRE(numbers.size() == 100);
    REQUIRE(inEven.c==51);
    REQUIRE(inOdd.c==50);
}

所以这是我必须为这个问题解决的测试用例,我不允许改变它。

1 个答案:

答案 0 :(得分:0)

请参阅我的自我解释的代码:

#include "stdafx.h"    
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;


condition_variable cv;
bool odd = false;

typedef  mutex TestMutex;

void incOdd(std::vector<uint8_t> *numbers,TestMutex *inEven,TestMutex *inOdd) {

    for (uint8_t i = 0; i < 100; i++) {
        if (i % 2 == 0) {
            unique_lock<mutex> lock(*inEven);
            cv.wait(lock, []() { return odd == false; });
            numbers->push_back(i);
            odd = true;
            cv.notify_one();
        }

    }

}

void incEven(std::vector<uint8_t> *numbers, TestMutex *inEven, TestMutex *inOdd) {

    for (uint8_t i = 0; i < 100; i++) {


        if (i % 2 != 0) {

            unique_lock<mutex> lock(*inEven);
            cv.wait(lock, []() { return odd == true; });
            numbers->push_back(i);
            odd = false;
            cv.notify_one();
        }

    }
}

int main()
{
    vector<uint8_t> vec;
    TestMutex mu;
    TestMutex rmu; // redundant
    thread thread1([&]() { incEven(&vec,&mu,&rmu); });
    thread thread2([&]() { incOdd(&vec,&mu,&rmu); });

    thread1.join();
    thread2.join();

    for (auto e : vec)
        cout << int(e) << endl;

    return 0;
}