这里我们直接使用C++11提供的库函数来进行实现。
简单示例代码如下:
#include<iostream> #include<thread> using namespace std; void workFun() { for (int n = 0; n < 4; n++) cout << "Hello,other thread." << endl; }//抢占式 int main() { thread t(workFun); t.detach(); //t.join(); for (int n = 0; n < 4; n++) cout << "Hello,main thread." << endl; while (true) { } return 0; }需要注意的几个点:
main线程结束,整个进程执行结束,其它附属线程也随之结束。使用join()的话,主线程会等其它线程执行完才继续执行;而使用detach()则并行执行。测试代码如下:
#include<iostream> #include<thread> using namespace std; void workFun(int index) { for (int n = 0; n < 4; n++) cout << index << "Hello,other thread." << endl; }//抢占式 int main() { thread t[4]; for (int n = 0; n < 4; n++) { t[n] = thread(workFun,n); } for (int n = 0; n < 4; n++) { t[n].join(); //t[n].detach(); } for (int n = 0; n < 4; n++) cout << "Hello,main thread." << endl; while (true) { } return 0; }对于线程数组来说,我们使用join各个线程之间是可以并行运行的。如果有多个线程对象,我们只调用了一个线程对象的join方法,那么所有的线程都会以join的方式执行,就表现为并行执行。但是,在程序执行结束前所有的线程对象都需要调用一次join方法(只能调用一次),否则程序会出现异常。
在上面的代码中我们多个线程中,cout属于共享资源,在输出的时候很容易出问题。我们这里使用一下锁,保证共享资源的安全性。代码如下:
#include<iostream> #include<thread> using namespace std; void workFun(int index) { for (int n = 0; n < 4; n++) cout << index << "Hello,other thread." << endl; }//抢占式 int main() { thread t[4]; for (int n = 0; n < 4; n++) { t[n] = thread(workFun,n); } for (int n = 0; n < 4; n++) { t[n].join(); //t[n].detach(); } for (int n = 0; n < 4; n++) { //临界区域-开始 m.lock(); cout << "Hello,main thread." << endl; m.unlock(); //临界区域-结束 } while (true) { } return 0; }为了防止上锁后没解锁,于是诞生了自解锁,原理和智能指针类似。
示例代码:
mutex m; int sum = 0; void workFun(int index) { for (int n = 0; n < 20000000; n++) { //自解锁 lock_guard<mutex> lg(m); //临界区域-开始 //m.lock(); sum++; //m.unlock(); //临界区域-结束 } }//抢占式自解锁源码:
// CLASS TEMPLATE lock_guard template <class _Mutex> class lock_guard { // class with destructor that unlocks a mutex public: using mutex_type = _Mutex; explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock _MyMutex.lock(); } lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) { // construct but don't lock } ~lock_guard() noexcept { _MyMutex.unlock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; private: _Mutex& _MyMutex; };对于一些基本类型,我们可以将其定义为原子类型,避免作为共享资源运算时需要使用锁。原子类型相对于锁,性能有很大的提升。
示例代码如下:
#include<iostream> #include<thread> #include<mutex>//锁 #include<atomic>//原子 #include"CELLTimestamp.hpp" using namespace std; //原子操作 原子 分子 mutex m; const int tCount = 4; atomic_int sum = 0; void workFun(int index) { for (int n = 0; n < 20000000; n++) { //自解锁 //lock_guard<mutex> lg(m); //临界区域-开始 //m.lock(); sum++; //m.unlock(); //临界区域-结束 }//线程安全 线程不安全 //原子操作 计算机处理命令时最小的操作单位 //cout << index << "Hello,main thread." << n << endl; }//抢占式 int main() { thread t[tCount]; for (int n = 0; n < tCount; n++) { t[n] = thread(workFun, n); } CELLTimestamp tTime; for (int n = 0; n < tCount; n++) { t[n].join(); //t[n].detach(); } cout << tTime.getElapsedTimeInMilliSec() << ",sum=" << sum << endl; sum = 0; tTime.update(); for (int n = 0; n < 80000000; n++) { sum++; } cout << tTime.getElapsedTimeInMilliSec() << ",sum=" << sum << endl; cout << "Hello,main thread." << endl; return 0; }参考资料:
C++ 百万并发网络通信引擎架构与实现 (服务端、客户端、跨平台) Version 1.0