1

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

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

}
4

3 回答 3

2

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

std::atomic_uint counter = 0;

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

于 2015-11-08T04:50:44.707 回答
1

您可能正在寻找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;
}
于 2015-11-08T05:01:40.647 回答
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();
}
于 2015-11-08T06:02:31.600 回答