共享变量C ++的两个线程

时间:2015-11-08 04:37:00

标签: c++ multithreading synchronization atomic stdatomic

所以我有两个线程,他们共享相同的变量'counter'。我想通过仅在两个线程都达到该点时继续执行来同步我的线程。不幸的是,我进入死锁状态,因为我的线程没有改变它的检查变量。我的方式是:

volatile int counter = 0;

    Thread() {

             - some calculations - 

            counter++;
            while(counter != 2) {
               std::this_thread::yield();
            }
            counter = 0;

            - rest of the calculations -
    }

这个想法是因为我有2个线程,一旦它们到达那个点 - 在不同的时间 - 它们将增加计数器。如果计数器不等于2,则首先到达那里的线程必须等到另一个计数器递增计数器以便它们同步。有谁知道这里的问题在哪里?

要添加有关该问题的更多信息,我有两个线程可以对阵列执行一半的操作。一旦完成,我想确保他们都完成了他们的计算。一旦它们出现,我就可以通知打印机线程唤醒并执行打印和清除阵列的操作。如果我在两个线程完成之前执行此操作,则会出现问题。

伪代码:

Thread() {

    getLock()
    1/2 of the calculations on array
    releaseLock()

    wait for both to finish - this is the issue

    wake up printer thread

}

3 个答案:

答案 0 :(得分:2)

在这种情况下,必须使用原子计数器。

std::atomic_uint counter = 0;

在给定的示例中,也没有counter初始化的迹象。

答案 1 :(得分:1)

您可能正在寻找std::conditional_variable:条件变量允许一个线程发信号到另一个线程。因为它看起来不像你正在使用计数器,并且你只是用它来进行同步,所以这里有一些来自another answer的代码(免责声明:这是我的答案之一),显示std::conditional_variable处理不同线程上的逻辑,并围绕值执行同步:

unsigned int accountAmount;
std::mutex mx;
std::condition_variable cv;

void depositMoney()
{
    // go to the bank etc...
    // wait in line...
    {
        std::unique_lock<std::mutex> lock(mx);
        std::cout << "Depositing money" << std::endl;
        accountAmount += 5000;
    }
    // Notify others we're finished
    cv.notify_all();
}
void withdrawMoney()
{
    std::unique_lock<std::mutex> lock(mx);
    // Wait until we know the money is there
    cv.wait(lock);
    std::cout << "Withdrawing money" << std::endl;
    accountAmount -= 2000;
}
int main()
{
    accountAmount = 0;
    // Run both threads simultaneously:
    std::thread deposit(&depositMoney);
    std::thread withdraw(&withdrawMoney);
    // Wait for both threads to finish
    deposit.join();
    withdraw.join();
    std::cout << "All transactions processed. Final amount: " << accountAmount << std::endl;
    return 0;
}

答案 2 :(得分:0)

我会考虑使用倒计时锁存器。想法是让一个或多个线程阻塞,直到完成所需的操作。在这种情况下,您要等到两个线程都完成修改数组。

这是一个简单的例子:

#include <condition_variable>
#include <mutex>
#include <thread>

class countdown_latch
{
public:
    countdown_latch(int count)
        : count_(count)
    {
    }

    void wait()
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while (count_ > 0)
            condition_variable_.wait(lock);
    }

    void countdown()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        --count_;
        if (count_ == 0)
            condition_variable_.notify_all();
    }

private:
    int count_;
    std::mutex mutex_;
    std::condition_variable condition_variable_;
};

并且用法看起来像这样

std::atomic<int> result = 0;
countdown_latch latch(2);

void perform_work()
{
    ++result;
    latch.countdown();
}

int main() 
{
    std::thread t1(perform_work);
    std::thread t2(perform_work);

    latch.wait();

    std::cout << "result = " << result;

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