C++11 之前,C++ 语言没有对并发编程提供语言级别的支持。如果需要使用线程,windows系统需要使用CreateThread函数创建线程,而linux需要使用pthread库使用线程。C++11 中增加了线程以及线程相关的类,很方便地支持了并发编程。由于可以跨平台使用,大大增加了多线程程序的可移植性。
c++11添加的线程类std::thread
Member types
id Thread id (public member type)
native_handle_type Native handle type (public member type)
Member functions
(constructor) Construct thread (public member function)
(destructor) Thread destructor (public member function)
operator= Move-assign thread (public member function)
get_id Get thread id (public member function)
joinable Check if joinable (public member function)
join Join thread (public member function)
detach Detach thread (public member function)
swap Swap threads (public member function)
native_handle Get native handle (public member function)
hardware_concurrency [static] Detect hardware concurrency (public static member function)
Non-member overloads
swap (thread) Swap threads (function)
函数说明
thread ()
向构造函数中传入线程函数名和参数,构造一个线程对象,该对象表示新的可连接执行线程。
void foo(int,int,int,int);//线程函数
std::thread first (foo,1,2,3,4);//创建线程对象,调用函数foo,参数为1,2,3,4
get_id()
获取线程id
thread t(func);
cout << "线程t 的线程ID: " << t.get_id() << endl;
cout << "主线程的线程ID: " << this_thread::get_id() << endl;
join()
调用这个函数的线程被阻塞,直到线程对象构造时调用的函数返回。调用此函数后,当子线程执行完毕之后 join() 会清理当前子线程中的相关资源然后返回,线程对象变得非连接状态,并且可以安全销毁。
joinable()
判断主线程和子线程是否是连接状态,主线程和子线程之间有连接关系返回true,主线程和子线程之间没有连接关系返回值false
detach()
线程分离。子线程和主线程分离之后,在主线程中就不能再对这个子线程做任何控制了,比如:无法通过 join () 阻塞主线程等待子线程中的任务执行完毕,不能调用 get_id () 获取子线程的线程 ID。此时调用joinable()函数会返回false。
子线程detach后,相当于放飞自我,子线程的死活就与主线程没有关系了,不再由主线程释放资源,而是由操作系统负责释放该线程资源。
如果子线程分离后,主线程退出,子线程会不会继续存在?
我编辑以下代码进行测试
#include <iostream> // std::cout
#include <thread> // std::thread
#include <windows.h> // Sleep
void foo()
{
while(1){
Sleep(300);
std::cout<<"foo\n";
}
}
int main()
{
std::thread first (foo);
first.detach();
Sleep(1000);
std::cout << "main thread exit\n";
return 0;
}
可以看到,主线程退出后,子线程随之退出,并没有循环一直运行下去
可见线程分离后,并不是完全与主线程没有关系,只是其资源由操作系统回收,而主线程退出后,该线程也会退出。
线程中的数据
C++多线程程序中,每一个线程都有一个线程栈,它们相互独立,因此在线程栈中的数据,是不会被其他线程影响到。但是在内存中的数据段的数据,比如静态变量,全局变量等,是可以在全局被访问到的。
测试线程代码
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
void foo()
{
// do stuff...
std::cout<<"foo\n";;
std::cout<<"foo\n";;
}
void bar(int x)
{
// do stuff...
std::cout<<"bar argument:"<<x<<std::endl;
std::cout<<"bar argument:"<<x<<std::endl;
}
int main()
{
std::thread first (foo); // spawn new thread that calls foo()
std::thread second (bar,1); // spawn new thread that calls bar(0)
std::thread third (bar,0);
std::cout << "main, foo and bar now execute concurrently...\n";
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
third.join();
std::cout << "foo and bar completed.\n";
return 0;
}
编译链接,由于需要c++11特性的支持,gcc需要加参数-std=c++11
or -std=gnu++11
g++ TestThread.cpp -std=c++11
由于线程竞争的问题,会导致一条语句输出的不完整。并且我发现,这种竞争只会发生在同名函数之间,线程函数foo()的输出不会被函数bar()打断,而函数bar()的输出会被其它的线程函数bar()打断