zoukankan      html  css  js  c++  java
  • C++11 并发指南二(std::thread 详解)

    上一篇博客《C++11 并发指南一(C++11 多线程初探)》中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用法。

    std::thread 在 <thread> 头文件中声明,因此使用 std::thread 时需要包含 <thread> 头文件。

    std::thread 构造

    default (1)
    thread() noexcept;
    
    initialization (2)
    template <class Fn, class... Args>
    explicit thread (Fn&& fn, Args&&... args);
    
    copy [deleted] (3)
    thread (const thread&) = delete;
    
    move (4)
    thread (thread&& x) noexcept;
    • (1). 默认构造函数,创建一个空的 thread 执行对象。
    • (2). 初始化构造函数,创建一个 thread对象,该 thread对象可被 joinable,新产生的线程会调用 fn 函数,该函数的参数由 args 给出。
    • (3). 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
    • (4). move 构造函数,move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
    • 注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached.

    std::thread 各种构造函数例子如下(参考):

    #include <iostream>
    #include <utility>
    #include <thread>
    #include <chrono>
    #include <functional>
    #include <atomic>
     
    void f1(int n)
    {
        for (int i = 0; i < 5; ++i) {
            std::cout << "Thread " << n << " executing
    ";
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }
     
    void f2(int& n)
    {
        for (int i = 0; i < 5; ++i) {
            std::cout << "Thread 2 executing
    ";
            ++n;
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }
     
    int main()
    {
        int n = 0;
        std::thread t1; // t1 is not a thread
        std::thread t2(f1, n + 1); // pass by value
        std::thread t3(f2, std::ref(n)); // pass by reference
        std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
        t2.join();
        t4.join();
        std::cout << "Final value of n is " << n << '
    ';
    }

    move 赋值操作

    move (1)
    thread& operator= (thread&& rhs) noexcept;
    
    copy [deleted] (2)
    thread& operator= (const thread&) = delete;
    • (1). move 赋值操作,如果当前对象不可 joinable,需要传递一个右值引用(rhs)给 move 赋值操作;如果当前对象可被 joinable,则 terminate() 报错。
    • (2). 拷贝赋值操作被禁用,thread 对象不可被拷贝。

    请看下面的例子:

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <chrono>    // std::chrono::seconds
    #include <iostream>  // std::cout
    #include <thread>    // std::thread, std::this_thread::sleep_for
    
    void thread_task(int n) {
        std::this_thread::sleep_for(std::chrono::seconds(n));
        std::cout << "hello thread "
            << std::this_thread::get_id()
            << " paused " << n << " seconds" << std::endl;
    }
    
    /*
     * ===  FUNCTION  =========================================================
     *         Name:  main
     *  Description:  program entry routine.
     * ========================================================================
     */
    int main(int argc, const char *argv[])
    {
        std::thread threads[5];
        std::cout << "Spawning 5 threads...
    ";
        for (int i = 0; i < 5; i++) {
            threads[i] = std::thread(thread_task, i + 1);
        }
        std::cout << "Done spawning threads! Now wait for them to join
    ";
        for (auto& t: threads) {
            t.join();
        }
        std::cout << "All threads joined.
    ";
    
        return EXIT_SUCCESS;
    }  /* ----------  end of function main  ---------- */

    其他成员函数

  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/haippy/p/3236136.html
Copyright © 2011-2022 走看看