c++线程学习-1

《C++ Concurrencyin Action》读书笔记

1、使用g++编译多线程程序的时候需要加上-lpthread参数,如:

g++ -std=c++11–o run.out test.cpp –lpthread

2、多线程编程增加了头文件#include<thread>,标准c++库中对多线程支持的声明在新的头文件中,管理现成的函数和类在<thread>中声明,而保护共享数据的函数和类在其他头文件中声明。每个线程都必须具有一个初始函数,新线程的执行在这里开始,一般初始线程的main()函数,对于其他线程,可以在std::thread对象的构造函数中指定。

例子:

#include<iostream>

#include<thread>

using namespace std;

 

void thread_hello()

{

Cout <<“hello thread”<<endl;

}

Int main(void)

{

       Threadt(thread_hello);

t.join();

//t.detach();

return 0;

}//end

Join:线程的加入,可以确保线程在函数完成前结束,能保证局部变量在县城完成后才被销毁;jion()只能对给定的对象调用一次,如果对给已加入的线程再次join()操作时,将会导致错误,可以调用joinable()进行判断是否已经加入。

Detach:线程的分离,主调函数不等待线程结束。使用detach()会让线程在后台运行,意味着主线程不能与之直接交互。通常分离线程为守护线程(没有任何用户接口,并在后台运行的线程)。

3、在把函数对象传入到线程构造函数中时,需要注意:如果传递了一个临时变量(非命名的变量),c++编译器会将其解析为函数生命,而不是类型对象的定义,例如:

       Std::threadmy_thread(test_thread());

这里相当于声明了一个带有一个参数名为my_thread并但会一个std::thread对象的函数。解决这个问题的四种方式:

1) 在前面命名函数对象;

2) 使用多组括号,std::thread my_thread((test_thread()));

3) 使用c++11新的初始化语法:std::thread my_thread{test_thread()};//大括号括起来;

4) 使用lambda表达式(允许使用一个可以捕获局部变量的局部函数)。

 

4、为了防止主调函数执行完成后(使用了detach),新线程还在运行(可能会访问到已经销毁的变量),常规方法:使线程函数的功能齐全,将数据复制到县城中,而不是复制到共享数据中(引用和指针的不当使用)。

5、什么情况下使用分离线程:一个程序执行多个相同的线程人物,每个线程运行相同的代码,但是每个线程都是独立的,完成与否对其他线程都不会产生影响。

6、向线程函数传递参数,例:

     Void func(int i , std::string const&s);

     Std::thread t(func, 3, “hello”);//注意字面值常量(char const *)向std::string对象的转化

还可以传递一个成员函数指针作为线程函数,并提供一个合适的对象指针作为第一个参数。

7、不能通过赋一个新值给std::thread对象的方式来“丢弃”一个线程,std::thread支持移动,就意味着新线程的所有权可以在函数外进行转移。例:

Std::thread f()

{

     Void some_func();

     Return std::thread(some_func);

/*或者如下定义:

*std::thread t(some_func);

*return t;*/

}

8、当所有权可以在函数内部传递,就允许std::thread实例可作为参数进行传递。例:

Void f(std::threadt);

F(std::thread(some_function));

9、std::thread::hardware_concurrency(),该函数返回能同时并发在一个程序中的线程数量(多核系统中,返回值是cpu核心的数量)。

10、在确定了要使用的线程数量之后,通过创建一个std::vector<T>容器存放中间结果,并为线程创建一个std::vector<std::thread>容器,需要注意:启动线程的数量必须比num_threads小1,因为在启动之前已经有了一个主线程。

11、线程标识类型是std::thread::id,以两种方式可以获取:

     1)通过调用std::thread对象的成员函数get_id()来直接过去,如果std::thread对象没有与任何执行线程相关联,get_id()将返回std::thread::type默认构造值,这个值表示没有线程

     2)当前线程中调用std::this_thread::get_id()(该函数也定义在<thread>头文件中)。

Std::thread::id对象可以自由的拷贝和对比,因为标识符就可以复用。如果两个对象的std::thread::id相等,那它们就是同一个线程,或者都没有线程。如果不等,那么就代表了两个不同线程,或者一个有线程一个没有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值