标签: stdthread

控制台输出顺序会降低多线程程序的速度

编译以下代码时

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <mutex>

std::mutex cout_mut;

void task()
{
    for(int i=0; i<10; i++)
    {
        double d=0.0;
        for(size_t cnt=0; cnt<200000000; cnt++) d += 1.23456;

        std::lock_guard<std::mutex> lg(cout_mut);
        std::cout << d << "(Help)" << std::endl;
        //        std::cout << "(Help)" << d << std::endl;
    }
}

int main()
{
    std::vector<std::thread> all_t(std::thread::hardware_concurrency());

    auto t_begin = std::chrono::high_resolution_clock::now();

    for(auto& t : all_t) t = std::thread{task};
    for(auto& t : all_t) t.join();

    auto t_end = std::chrono::high_resolution_clock::now();

    std::cout << "Took : " << …
Run Code Online (Sandbox Code Playgroud)

concurrency mutex c++11 stdthread

8
推荐指数
1
解决办法
247
查看次数

当`sleep_until()`指定过去的时间点时,行为是否定义良好?

C++ 11标准讨论了如果调整系统时钟以使传递到的时间点sleep_until()现在已经过去会发生什么 - 但是当指定的时间点已经存在时,我无法看到解决该问题的任何地方.过去.

我是否只是忽略了某些东西,或者它是否真的没有指定 - 即使是UB或实现定义的东西?

如果sleep_for()以负持续时间调用,则会出现类似的问题.

c++ language-lawyer c++11 c++-chrono stdthread

8
推荐指数
2
解决办法
648
查看次数

使用 native_handle() + pthread_cancel() 取消 std::thread

我正在将先前围绕 pthreads 的线程包装器转换为 std::thread。但是 c++11 没有任何方法可以取消线程。尽管如此,我需要取消线程,因为它们可能在外部库中执行非常冗长的任务。

我正在考虑在我的平台中使用为我提供 pthread_id 的 native_handle。我在 Linux (Ubuntu 12.10) 中使用 gcc 4.7。这个想法是:

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

using namespace std;

int main(int argc, char **argv) {
    cout << "Hello, world!" << endl;

    auto lambda = []() {
        cout << "ID: "<<pthread_self() <<endl;
        while (true) {
            cout << "Hello" << endl;
            this_thread::sleep_for(chrono::seconds(2));
        }
    };

    pthread_t id;
    {
        std::thread th(lambda);

        this_thread::sleep_for(chrono::seconds(1));

        id = th.native_handle();
        cout << id << endl;
        th.detach();
    }
    cout << "cancelling ID: "<< id …
Run Code Online (Sandbox Code Playgroud)

c++ gcc pthreads c++11 stdthread

7
推荐指数
1
解决办法
4251
查看次数

2个线程比1慢?

我正在玩耍,std::thread出现了一些奇怪的东西:

#include <thread>

int k = 0;

int main() {
    std::thread t1([]() { while (k < 1000000000) { k = k + 1; }});
    std::thread t2([]() { while (k < 1000000000) { k = k + 1; }});

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在使用clang ++编译上面的代码而没有优化时,我得到了以下基准:

real 0m2.377s  
user 0m4.688s  
sys  0m0.005s
Run Code Online (Sandbox Code Playgroud)

然后我将代码更改为以下内容:(现在只使用1个线程)

#include <thread>

int k = 0;

int main() {
    std::thread t1([]() { while (k < 1000000000) { k = k + 1; }});

    t1.join();

    return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ performance multithreading c++11 stdthread

7
推荐指数
1
解决办法
1027
查看次数

原始调用者被销毁后,std :: thread :: detach导致崩溃

struct Test {
    bool active{true};

    void threadedUpdate() {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        if(!active) // crashes here after Test instance is destroyed
            return; 
    }

    Test() { 
        std::thread([this]{ while(true) threadedUpdate(); }).detach();
    }

    ~Test() { 
        // somehow stop the detached thread?
    } 
};
Run Code Online (Sandbox Code Playgroud)

Test初始化实例时,它会生成并分离std::thread在后台运行的实例.当同一个实例被销毁时,前面提到的线程试图访问该active成员,该成员与实例一起被销毁,导致崩溃(和一个AddressSanitizer回溯).

有没有办法停止分离的线程~Test()

设计很糟糕.如果正确生成/处理在调用者被销毁之前,如何在后台运行线程?

c++ multithreading detach c++11 stdthread

7
推荐指数
2
解决办法
2962
查看次数

unique_lock使用互斥锁有什么特殊用途?

我不太清楚为什么std::unique_lock<std::mutex>仅仅使用普通锁是有用的.我正在看的代码中的一个例子是:

{//aquire lock

        std::unique_lock<std::mutex> lock(queue_mutex);

        //add task
        tasks.push_back(std::function<void()>(f));

}//release lock
Run Code Online (Sandbox Code Playgroud)

为什么会偏爱

queue_mutex.lock();

//add task
//...

queue_mutex.unlock();
Run Code Online (Sandbox Code Playgroud)

这些代码片段完成同样的事情吗?

c++ mutex threadpool c++11 stdthread

7
推荐指数
2
解决办法
960
查看次数

从不从 std::packaged_task 检索 std::future 的结果是否安全?

std::future从 a创建 a 是否安全std::packaged_task,该 a 在单独的线程上执行,但并不总是检索其结果?

#include <future>
#include <thread>

class Result {
  Result() {}
  ~Result() {}
};

void foo() {
  std::packaged_task<Result()> task(..);
  auto future = task.get_future();
  std::thread thread(std::move(task), ...);
  thread.detach();
  if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::ready) {
    auto result = future.get();  <--- Task didn't take too long, retrieve future result
    ...
  }
}  <--- Task is taking too long, just abort and never call future.get()
Run Code Online (Sandbox Code Playgroud)

它似乎适用于 Clang / libc++: ~Result()is Called on the returned result by the …

c++ packaged-task c++11 stdthread

7
推荐指数
1
解决办法
834
查看次数

正确的方法来暂停和恢复std :: thread

std::thread在我的C++代码中使用一个不断轮询一些数据并将其添加到缓冲区.我使用a C++ lambda来启动这样的线程:

StartMyThread() {

    thread_running = true;
    the_thread = std::thread { [this] {
        while(thread_running) {
          GetData();
        }
    }};
}
Run Code Online (Sandbox Code Playgroud)

thread_runningatomic<bool>在类头中声明的.这是我的GetData功能:

GetData() {
    //Some heavy logic which needs to be executed in a worker thread
}
Run Code Online (Sandbox Code Playgroud)

接下来我还有一个StopMyThread函数,我将其设置thread_running为false,以便它退出while中的while循环lambda block.

StopMyThread() {
  thread_running = false;
  the_thread.join();
}
Run Code Online (Sandbox Code Playgroud)

它运作良好.线程启动和停止而不会崩溃.

此C++代码用于iOS,Android,OS X和Windows.我的应用程序UI有一个按钮,要求我按下按钮启动和停止线程; 这个按钮可以在某些场合经常使用.我可以在停止或启动线程时看到UI中的瞬间延迟.

我的问题是: 在C++中,这是经常启动/停止线程的正确方法吗?我认为通过这种逻辑,我每次都在创建一个新的线程.据我所知,创建一个新线程会使操作系统分配大量新资源,这些资源可能会耗费时间.我认为这是我正在做的错误.我怎么能避免这个?

如何在整个应用程序生命周期中不重复分配新线程的情况下使用相同的线程,并在需要时播放/暂停?

c++ lambda c++11 stdthread c++14

7
推荐指数
1
解决办法
2万
查看次数

将const引用传递给临时/匿名lambda到std :: thread构造函数是否安全?

继这个问题之后:可以通过参考传递一段时间吗?

我有一个固定的代码片段:

// global variable
std::thread worker_thread;

// Template function
template <typename Functor>
void start_work(const Functor &worker_fn)  // lambda passed by const ref
{
    worker_thread = std::thread([&](){
        worker_fn();
    });
}
Run Code Online (Sandbox Code Playgroud)

这被称为:

void do_work(int value)
{
    printf("Hello from worker\r\n");
}

int main()
{
    // This lambda is a temporary variable...
    start_work([](int value){ do_work(value) });
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但我担心将临时lambda传递给线程构造函数,因为线程将运行,但函数start_work()将返回并且temp-lambda将超出范围.

但是我正在查看定义的std :: thread构造函数:

thread()noexcept; (1)(自C++ 11以来)

thread(thread && other)noexcept; (2)(自C++ 11起)

template <class Function,class ... Args> explicit thread(Function && f,Args && ... args); (3)(自C++ …

c++ lambda pass-by-reference stdthread

7
推荐指数
1
解决办法
348
查看次数

为什么 std::thread() 按值传递参数(以及为什么 Stroustrup 博士给出的原因是不正确的)?

引自 The C++ Programming Language(作者:Bjarne Stroustrup),第1213页

\n
\n

线程构造函数是variadic templates(\xc2\xa728.6)。这意味着要将引用传递给线程构造函数,我们必须使用引用包装器 (\xc2\xa733.5.1)。

\n

例如:

\n
void my_task(vector<double>& arg);\nvoid test(vector<double>& v)\n{\n    thread my_thread1 {my_task,v};           //oops: pass a copy of v\n    thread my_thread2 {my_task,ref(v)};      // OK: pass v by reference\n    thread my_thread3 {[&v]{ my_task(v); }}; // OK: dodge the ref() problem\n    // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

问题是variadic templates通过引用目标函数传递参数没有问题。

\n

例如:

\n
void g(int& t)\n{\n}\n\ntemplate <class... T>\nvoid f(T&&... t)\n{\n    g(std::forward<T>(t)...);\n}\n\nint main()\n{\n    int i;\n    f(i);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

按值传递的唯一原因是标准要求在参数上std::thread …

c++ reference stdthread

7
推荐指数
2
解决办法
151
查看次数