两个线程共享变量C++

Two threads sharing variable C++

本文关键字:线程 共享变量 C++ 两个      更新时间:2023-10-16

所以我有两个线程,它们共享同一个变量"counter"。我想同步我的线程,只在两个线程都达到那个点后才继续执行。不幸的是,我进入了死锁状态,因为我的线程没有改变它的检查变量。我的方法是:

volatile int counter = 0;
    Thread() {
             - some calculations - 
            counter++;
            while(counter != 2) {
               std::this_thread::yield();
            }
            counter = 0;
            - rest of the calculations -
    }

这个想法是,由于我有两个线程,一旦它们在不同的时间达到那个点,它们就会增加计数器。如果计数器不等于2,那么首先到达那里的线程将不得不等待,直到另一个线程增加了计数器,以便同步它们。有人知道问题出在哪里吗?

为了添加有关该问题的更多信息,我有两个线程,它们对一个数组执行一半的操作。一旦完成,我想确保他们都完成了计算。一旦它们被激活,我就可以向打印机线程发出信号,让其唤醒并执行打印和清除数组的操作。如果我在两个线程都完成之前都这样做,就会出现问题。

伪代码:

Thread() {
    getLock()
    1/2 of the calculations on array
    releaseLock()
    wait for both to finish - this is the issue
    wake up printer thread
}

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

std::atomic_uint counter = 0;

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

您可能正在寻找std::conditional_variable:条件变量允许一个线程向另一个线程发出信号。因为它看起来不像你在使用计数器,而且你只是在使用它进行同步,所以这里有一些来自另一个答案的代码(免责声明:这是我的答案之一),它显示了不同线程上的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;
}

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

这里有一个简单的例子:

#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();
}