zoukankan      html  css  js  c++  java
  • C++ 并发编程 01 线程api

    1.使用多线程的好处: 提高性能分离关注点 

    2. 多线程所在头文件 <thread>

    3. 使用线程方式为std::thread(functioncall),如:

    #include <iostream>
    #include <thread>
    
    void hello()
    {
        std::cout<<"Hello Concurrent World
    ";
    }
    
    int main()
    {
        std::thread t(hello);
        t.join();
    }

    4. thread api:

    • constructor

    使用一个函数,或者是一个callable object来初始化一个thread 对象。实际就是associate一个thread对象和一个thread of execution,便能够开启一个线程了。当然你也可以声明一个thread对象而不对其associate,这个时候有些方法就不能执行。

    注意:

    (1)如果和thread 对象绑定的execution函数有参数,那么也是通过associate时,一同传入的。如果thread对象绑定的execution函数有返回值,那么可以通过传入一个引用,或者指针将返回值,传递出来。当然对于返回值,后面章节会有其他解决办法。

    (2)一旦一个thread对象,绑定了execution函数,在其线程终止之前必须要对其进行处理。不能使其在开启这个thread的进程结束之后,还在运行。否则系统会调用std::thread::terminate()出错。解决办法有两个A。join声明由创建它的程序来回收。detach表示将其run in background,最后系统回收。

    • join

    join兼有等待某个thread结束与回收其资源的作用。某个associate的对象,只能join一次,可以通过函数std::thread::joinable来判定。

    • detach  调用后线程将在后台运行run in background,该线程与这个进程内的其他线程无关了。但是若这个线程的进程结束,这个线程也会被终止。

    注意: 某个associate了execution function的对象,也只能detach一次。可以用joinable来判定。return,exit都是结束进程。UNIX结束线程可以用thread_cancel

    #include <thread>
    #include <Windows.h>
    
    void do_something(int& i)
    {
        ++i;
    }
    
    struct func
    {
        int& i;
    
        func(int& i_):i(i_){}
    
        void operator()()
        {
            for(unsigned j=0;j<1000000;++j)
            {
                do_something(i);
            }
        }
    };
    
    
    void oops()
    {
        int some_local_state=0;
        func my_func(some_local_state);
        std::thread my_thread(my_func);
        my_thread.detach();
    }
    
    int main()
    {
    
        oops();
    
        //::Sleep(10 * 1000);
    }

    上述示例中,oops启动了一个线程,并调用detach()在后台运行,其实一个耗时线程,进行100万次累加操作,但是主线程main()可能已经结束退出,所以该程序可能会出现错误

    • std::move

    这个函数可以显式转移线程的拥有权,线程对象不能赋值,但是可以转移。相当于,转移那个associate关系。被move的thread 对象就没有绑定的execution function了。

    • hardware_concurrency

    static方法,返回这台主机的硬件并发数,即内核数量。

    • get_id()/ this_thread::get_id()

    返回线程的id,返回的id类型是std::thread::id类型的。

    注意:可以相互比较大小,如果两个大小相同,他们就是相同的thread。

            必须要associate execution function的thread object才有有意义的数字thread id。返回没有associate的,会显示没有绑定,但不会终止程序。

    5. 线程的启动

    在定义thread创建的时候即启动线程

    6. 线程的委托对象

    函数/ Callable对象实例(即带重载operator()的对象class或struct)

    如下面代码中的CallableStruct结构体即为Callable对象,

    struct CallableStruct
    {
        int& i;
    
        func(int& i_):i(i_){}
    
        void operator()()
        {
            for(unsigned j=0;j<1000000;++j)
            {
                 std::cout<<j<<std::endl;
            }
        }
    };
    
    int some_local_state=0;
    CallableStruct  my_CallableStruct(some_local_state);
    std::thread my_thread(my_CallableStruct);
    my_thread.detach();

    使用Callable对象实例初始化线程时推荐使用以下方式:

    std::thread my_thread((CallableStruct()));  // 多加一层括号将对象的实例化给括起来
    std::thread my_thread{CallableStruct()};   //C++ 11 初始化语法


    std::thread my_thread(CallableStruct());  // 错误,意思变成了指向一个无参数,返回值为CallableStruct的函数指针
  • 相关阅读:
    thinkphp3.2v
    ng-select 下拉的两种方式
    angular的时间指令 以及防止闪烁问题
    angularjs中的几种工具方法
    运用正则+replace+substring将一段英语的字母大写 angurlar运用自定义指令filter完成首字母大写
    angularjs bind与model配合双向绑定 表达式方法输出
    ajax跨域问题
    团队作业一
    校外实习报告(四)
    校外实习报告(三)
  • 原文地址:https://www.cnblogs.com/lenmom/p/9083961.html
Copyright © 2011-2022 走看看