#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void myrun()
{while(true){cout<<"I am a thread"<<endl;sleep(1);}
}
int main()
{thread t(myrun);t.join();return 0;
}
如果不添加-lpthread就会报错。
用纯c++的接口创建线程时,在Linux中还是要包含线程库。
这说明c++的那些库本质就是pthread原生线程库的封装。
这样,我们学习别的语言,只需要学习接口,因为我们知道底层是一样的。
说到底,这样的设计就是为了跨平台性。
接下来了解一下线程的局部存储。
__thread可以给每个执行流一个变量。
在编译链接库时,就会给每一个变量在线程局部存储中开辟空间。
#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
__thread int g_val=100;
void myrun()
{while(g_val--){cout<<"I am a new thread"<<" "<<g_val<<" "<<&g_val<<endl;sleep(1);}
}
int main()
{thread t(myrun);while(g_val--){cout<<"I am main thread"<<" "<<g_val<<" "<<&g_val<<endl;sleep(2);}t.join();return 0;
}
下面是多线程的一个简单模版。
//test.hpp
#include<iostream>
#include<thread>
#include<unistd.h>
#include<functional>
#include<vector>
using namespace std;
template<class T>
using func_t=function<void(T)>;//返回值为void,参数为T
template<class T>
class Thread
{public:Thread(func_t<T> func,const string&name,T data):_tid(0),_func(func),_threadname(name),isrunning(false),_data(data){}static void*ThreadRoutine(void*args){//(void)args;//仅仅是为了防止编译器有告警Thread*ts=static_cast<Thread*>(args);ts->_func(ts->_data);return nullptr;}bool Start(){int n=pthread_create(&_tid,nullptr,ThreadRoutine,this);if(n==0){isrunning=true;return true;}return false;}bool Join(){if(!isrunning) return true;int n=pthread_join(_tid,nullptr);if(n==0){isrunning=false;return true;}return false;}string GetThreadName(){return _threadname;}bool IsRunning(){return isrunning;}~Thread(){}private:pthread_t _tid;string _threadname;bool isrunning;func_t<T> _func;T _data;
};
#include"test.hpp"
using namespace std;
string GetThreadName()
{static int number=1;char name[64];snprintf(name,sizeof name,"Thread - %d",number++);return name;
}
void print(int num)
{while(num--){cout<<"hello world"<<num<<endl;sleep(1);}
}
int main()
{int num=5;vector<Thread<int>> Threads;while(num--){Threads.push_back(Thread<int>(print,GetThreadName(),10));}for(auto &t:Threads){cout<<t.GetThreadName()<<" is running? "<<t.IsRunning()<<endl;}for(auto&t:Threads){t.Start();}for(auto &t:Threads){cout<<t.GetThreadName()<<" is running? "<<t.IsRunning()<<endl;}for(auto &t:Threads){t.Join();}// Thread t(print,GetThreadName());// cout<<"Is thread running?"<<t.IsRunning()<<endl;// t.Start();// cout<<"Is thread running?"<<t.IsRunning()<<endl;// t.Join();return 0;
}