• C++ 线程


    thread

    类 thread 表示单个执行线程。线程允许多个函数同时执行。

    线程在构造关联的线程对象时立即开始执行(等待任何OS调度延迟),从提供给作为构造函数参数的顶层函数开始。顶层函数的返回值将被忽略,而且若它以抛异常终止,则调用 std::terminate 。顶层函数可以通过 std::promise 或通过修改共享变量(可能需要同步,见 std::mutex 与 std::atomic )将其返回值或异常传递给调用方。

    std::thread 对象也可能处于不表示任何线程的状态(默认构造、被移动、 detach 或 join 后),并且执行线程可能与任何 thread 对象无关( detach 后)。

    没有两个 std::thread 对象会表示同一执行线程; std::thread 不是可复制构造 (CopyConstructible) 或可复制赋值 (CopyAssignable) 的,尽管它可移动构造 (MoveConstructible) 且可移动赋值 (MoveAssignable) 。

    成员类型
    	native_handle_type (可选)	实现定义成员类
    成员类
    	id	表示线程的 id(公开成员类)
    
    (构造函数)	构造新的 thread 对象(公开成员函数)
    (析构函数)	析构 thread 对象,必须合并或分离底层线程(公开成员函数)
    operator= 	移动 thread 对象(公开成员函数)
    观察器
    	joinable	检查线程是否可合并,即潜在地运行于平行环境中(公开成员函数)
    	get_id	返回线程的 id(公开成员函数)
    	native_handle	返回底层实现定义的线程句柄(公开成员函数)
    	hardware_concurrency[静态]	返回实现支持的并发线程数(公开静态成员函数)
    操作
    	join	等待线程完成其执行(公开成员函数)
    	detach	容许线程从线程句柄独立开来执行(公开成员函数)
    	swap	交换二个thread对象(公开成员函数)
    非成员函数
    	std::swap(std::thread)(C++11)特化 std::swap 算法(函数)
    
    #include <iostream>
    #include <utility>
    #include <thread>
    #include <chrono>
     
    void f1(int n)
    {
        for (int i = 0; i < 5; ++i) {
            std::cout << "Thread 1 executing\n";
            ++n;
            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";
            ++n;
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }
     
    class foo
    {
    public:
        void bar()
        {
            for (int i = 0; i < 5; ++i) {
                std::cout << "Thread 3 executing\n";
                ++n;
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
            }
        }
        int n = 0;
    };
     
    class baz
    {
    public:
        void operator()()
        {
            for (int i = 0; i < 5; ++i) {
                std::cout << "Thread 4 executing\n";
                ++n;
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
            }
        }
        int n = 0;
    };
     
    int main()
    {
        int n = 0;
        foo f;
        baz b;
        std::thread t1; // t1 不是线程
        std::thread t2(f1, n + 1); // 按值传递
        std::thread t3(f2, std::ref(n)); // 按引用传递
        std::thread t4(std::move(t3)); // t4 现在运行 f2() 。 t3 不再是线程
        std::thread t5(&foo::bar, &f); // t5 在对象 f 上运行 foo::bar()
        std::thread t6(b); // t6 在对象 b 的副本上运行 baz::operator()
        std::thread t7{[]{ std::cout << "Thread 7 executing\n"; }}; // std::thread 的参数也可以是函数对象或者 lambda
        t2.join();
        t4.join();
        t5.join();
        t6.join();
        t7.join();
        std::cout << "Final value of n is " << n << '\n';
        std::cout << "Final value of f.n (foo::n) is " << f.n << '\n';
        std::cout << "Final value of b.n (baz::n) is " << b.n << '\n';
    }
    

    join

    阻塞当前线程直至 this 所标识的线程结束其执行。this 所标识的线程的完成同步于对应的从 join() 成功返回。*this 自身上不进行同步。同时从多个线程在同一thread 对象上调用 join() 构成数据竞争,导致未定义行为。

    joinable

    检查 std::thread 对象是否标识活跃的执行线程。具体而言,若 get_id() != std::id() 则返回 true 。故默认构造的 thread 不可结合。结束执行代码,但仍未结合的线程仍被当作活跃的执行线程,从而可结合。

    #include <iostream>
    #include <thread>
    #include <chrono>
     
    void foo()
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
     
    int main()
    {
        std::thread t;
        std::cout << "before starting, joinable: " << std::boolalpha << t.joinable()
                  << '\n';
     
        t = std::thread(foo);
        std::cout << "after starting, joinable: " << t.joinable() 
                  << '\n';
     
        t.join();
        std::cout << "after joining, joinable: " << t.joinable() 
                  << '\n';
    }
    
    输出:
    
    before starting, joinable: false
    after starting, joinable: true
    after joining, joinable: false
    

    detach

    从 thread 对象分离执行线程,允许执行独立地持续。一旦该线程退出,则释放任何分配的资源。调用 detach 后 *this 不再占有任何线程。

    swap

    交换二个 thread 对象的底层柄。

    #include <iostream>
    #include <thread>
    #include <chrono>
     
    void foo()
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
     
    void bar()
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
     
    int main()
    {
        std::thread t1(foo);
        std::thread t2(bar);
     
        std::cout << "thread 1 id: " << t1.get_id() << '\n'
                  << "thread 2 id: " << t2.get_id() << '\n';
     
        std::swap(t1, t2);
     
        std::cout << "after std::swap(t1, t2):" << '\n'
                  << "thread 1 id: " << t1.get_id() << '\n'
                  << "thread 2 id: " << t2.get_id() << '\n';
     
        t1.swap(t2);
     
        std::cout << "after t1.swap(t2):" << '\n'
                  << "thread 1 id: " << t1.get_id() << '\n'
                  << "thread 2 id: " << t2.get_id() << '\n';
     
        t1.join();
        t2.join();
    }
    

    可能的输出:

    thread 1 id: 140185268262656
    thread 2 id: 140185259869952
    after std::swap(t1, t2):
    thread 1 id: 140185259869952
    thread 2 id: 140185268262656
    after t1.swap(t2):
    thread 1 id: 140185268262656
    thread 2 id: 140185259869952
    
  • 相关阅读:
    Python内置函数(49)——isinstance
    Python内置函数(48)——__import__
    Python内置函数(47)——vars
    Python内置函数(46)——format
    Python内置函数(45)——ascii
    Python内置函数(44)——len
    Python内置函数(43)——type
    Python内置函数(42)——hash
    Python内置函数(41)——id
    Linux下redis常用命令
  • 原文地址:https://www.cnblogs.com/chengmf/p/15957636.html
Copyright © 2020-2023  润新知