c++ - 在 VS2012 中使用 C++11 条件变量

标签 c++ multithreading c++11 visual-studio-2012 condition-variable

我无法让代码在一个简单的 VS2012 控制台应用程序中可靠地工作,该应用程序由使用 C++11 条件变量的生产者和消费者组成。我的目标是生成一个可靠的小程序(用作更复杂程序的基础),该程序使用 3 个参数 wait_for 方法,或者可能是我在这些网站上收集的代码中的 wait_until 方法:

condition_variable : wait_for , wait_until

我想将 3 个参数 wait_for 与如下所示的谓词一起使用,除非它需要使用类成员变量以便稍后对我最有用。运行大约一分钟后,我收到“访问冲突写入位置 0x__”或“将无效参数传递给服务或函数”作为错误。

steady_clock 和第二个参数 wait_until 是否足以替代第三个参数 wait_for?我也尝试过但没有成功。

有人可以展示如何让下面的代码无限期地运行而不会出现任何错误或奇怪的行为,无论是夏令时或互联网时间同步的挂钟时间发生变化吗?

指向可靠示例代码的链接可能同样有用。

// ConditionVariable.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
#include <atomic>

#define TEST1

std::atomic<int> 
//int 
    qcount = 0; //= ATOMIC_VAR_INIT(0);

int _tmain(int argc, _TCHAR* argv[])
{
    std::queue<int> produced_nums;
    std::mutex m;
    std::condition_variable cond_var;
    bool notified = false;
    unsigned int count = 0;

    std::thread producer([&]() {
        int i = 0;
        while (1) {
            std::this_thread::sleep_for(std::chrono::microseconds(1500));
            std::unique_lock<std::mutex> lock(m);
            produced_nums.push(i);
            notified = true;
            qcount = produced_nums.size();
            cond_var.notify_one();
            i++;
        }   
        cond_var.notify_one();
    }); 

    std::thread consumer([&]() {
        std::unique_lock<std::mutex> lock(m);
        while (1) {
#ifdef TEST1
            // Version 1
            if (cond_var.wait_for(
                lock,
                std::chrono::microseconds(1000),
                [&]()->bool { return qcount != 0; }))
            {
                if ((count++ % 1000) == 0)
                    std::cout << "consuming " << produced_nums.front    () << '\n';
                produced_nums.pop();
                qcount = produced_nums.size();
                notified = false;
            }
#else
            // Version 2
            std::chrono::steady_clock::time_point timeout1 =
                std::chrono::steady_clock::now() +
                //std::chrono::system_clock::now() +
                std::chrono::milliseconds(1);

            while (qcount == 0)//(!notified)
            {
                if (cond_var.wait_until(lock, timeout1) == std::cv_status::timeout)
                    break;
            }

            if (qcount > 0)
            {
                if ((count++ % 1000) == 0)
                std::cout << "consuming " << produced_nums.front() << '\n';
                produced_nums.pop();
                qcount = produced_nums.size();
                notified = false;
            }
#endif
        }
    });

    while (1);
    return 0;
}

Visual Studio Desktop Express 安装了 1 个重要更新,Windows Update 没有其他重要更新。我使用的是 Windows 7 32 位。

最佳答案

可悲的是,这实际上是 VS2012 的 condition_variable 实现中的一个错误,修复不会被修补。当它发布时你必须升级到 VS2013。

参见:

http://connect.microsoft.com/VisualStudio/feedback/details/762560

关于c++ - 在 VS2012 中使用 C++11 条件变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13866088/

相关文章:

templates - 使用可变参数模板建立索引

C++ 数组和 make_unique

c++ - 受条件限制的模板特化

c++ - std::atomic 可以用减量抵消增量吗?

c++ - 如何在 C++ 中通过相交或不相交对子 vector 进行分组

c# - 以下场景的线程机制

c++ - 用 std::initializer_list 中的实例覆盖

c++ - 我的 C++ 程序出现错误

java - 限制部分代码的 Activity 线程数

c# - 重温 Thread.Abort() - 它安全吗?