multithreading - 为什么这个小的 c++11 多线程程序会出现段错误

标签 multithreading c++11 race-condition undefined-behavior

为什么这个程序会出现段错误。我尝试使用 gdb 解决这个问题,但没有成功。

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>

using namespace std;

condition_variable cv;
mutex cv_m;

mutex m;

int  count = 0;
#define COUNT_DONE  10
#define COUNT_HALT1  3
#define COUNT_HALT2  6

void functionCount1()
{
   for(;;)
   {
        m.lock();
        count++;
        cout << "Counter value functioncount1: " << count << endl;
        m.unlock();

        if(count >= COUNT_DONE)
                return;
    }
}

void functionCount2()
{
    for(;;)
    {
        m.lock();
        count++;
        cout << "Counter value functionCount2: " << count << endl;
        m.unlock();

        if(count >= COUNT_DONE) return;
    }
}

int main()
{
    thread t1(functionCount1), t2(functionCount2);
    t1.join();
    t2.join();
    return 0;
}

最佳答案

您的程序存在未定义的行为:对 functionCount1functionCount2 中互斥体外部的 count 的访问属于数据争用。 With the UB corrected, it seems fine :

#include <iostream>
#include <mutex>
#include <thread>

using namespace std;

mutex m;
int  count = 0;
#define COUNT_DONE  10

void functionCount(const char* name)
{
   for(;;)
   {
        m.lock();
        auto c = ++count;
        m.unlock();

        cout << "Counter value " << name << ": " << c << endl;
        if(c >= COUNT_DONE)
                return;
    }
}

int main()
{
    thread t1(functionCount, "functionCount1"), t2(functionCount, "functionCount2");
    t1.join();
    t2.join();
}

或者如果你想变得“聪明”并迷惑你的代码审查者:

void functionCount(const char* name)
{
    for(;;)
    {
        auto c = (std::lock_guard<std::mutex>(m), count++);
        cout << "Counter value " << name << ": " << c << endl;
        if(c >= count_done)
            break;
    }
}

关于multithreading - 为什么这个小的 c++11 多线程程序会出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20995897/

相关文章:

c - 读取器/写入器伪代码中潜在的竞争条件

multithreading - 跨线程合并更改时如何防止竞争状况?

c++ - 如何在 C++ 中将 std::thread::id 转换为字符串?

multithreading - Entity Framework 创建模型时无法使用上下文

c++ - 使用 vs typedef 的别名

c++ - "Defaulted" move 构造函数和赋值 - 奇怪的行为

c++ - clang vs gcc - 优化包括 operator new

c++ - 何时使用 QThread::exec()

java - 使用多线程打印奇数和偶数

c - 这种条件变量的使用是否总是受到丢失信号竞争的影响?