【Linux】多线程_3

avatar
作者
猴君
阅读量:1

文章目录


九、多线程

3. C++11中的多线程

Linux中是根据多线程库来实现多线程的,C++11也有自己的多线程,那它的多线程又是怎样的?我们来使用一些C++11的多线程。
Makefile

testThread: testThread.cc 	g++ -o $@ $^ -std=c++11 .PHONY: clean clean: 	rm -f testThread 

testThread.cc

#include <iostream> #include <thread> #include <unistd.h> using namespace std;  void threadrun(int num) {     while (num)     {         cout << "I am thread, num : " << num << endl;         sleep(1);         --num;     } }  int main() {     thread t1(threadrun, 10);     while (true)     {         cout << "I am main thread" << endl;         sleep(1);     }      t1.join();          return 0; } 

编译看看:
在这里插入图片描述
我们发现有问题(也可能是其他问题),这是怎么回事呢?其实是 C++11的多线程本质上是对原生线程的封装。所以同样需要链接 phread 动态库。
Makefile

testThread: testThread.cc 	g++ -o $@ $^ -std=c++11 -lpthread .PHONY: clean clean: 	rm -f testThread 

我们再试试:
在这里插入图片描述
确实大部分其编程语言的多线程都是对原生线程的封装,原因是为了可移植性。
我们在进程部分学过 非阻塞等待 ,进程在等待子进程退出时,可以执行其他任务,在线程这里,同样有这样的技术,叫做线程分离。我们要是不关注线程的结果,只需要线程把自己的任务完成,这种情况就可以将线程进行分离。
在这里插入图片描述
Makefile

testThread: testThread.cc 	g++ -o $@ $^ -std=c++11 -lpthread .PHONY: clean clean: 	rm -f testThread 

testThread.cc

#include <iostream> #include <pthread.h> #include <string> #include <unistd.h> using namespace std;  void* threadrun(void* args) {     string str = (const char*)args;     int cnt = 5;     while (true)     {         if (!(cnt--)) break;         cout << "I am a new thread " << endl;         sleep(1);     } }  int main() {     pthread_t tid;     pthread_create(&tid, nullptr, threadrun, (void*)"thread1");     // 线程分离     pthread_detach(tid);      while (true)     {         cout << "I am the main thread " << endl;         sleep(1);     }      return 0; } 

在这里插入图片描述

默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

joinable和分离是冲突的,一个线程不能既是joinable又是分离的。如果将线程分离了又对其join,就会出错。
线程分离底层依旧是属于进程,没有分开,线程分离只是一种状态,唯一的区别就是主线程不需要等待新线程。

4. 线程的简单封装

Makefile

testThread: testThread.cc 	g++ -o $@ $^ -std=c++11 -lpthread .PHONY: clean clean: 	rm -f testThread 

Thread.hpp

#ifndef __THREAD_HPP__ #define __THREAD_HPP__  #include <iostream> #include <pthread.h> #include <string> #include <functional> #include <unistd.h>  // 线程命名空间 namespace ThreadModule {     // 线程函数模板     template<typename T>     using func_t = std::function<void(T&)>;      // 线程模板     template<typename T>     class Thread     {     public:         Thread(func_t<T> func, T data, const std::string& name = "none-name")         :_func(func)         ,_data(data)         ,_threadname(name)         ,_stop(true)         {}          void Excute()         {             _func(_data);         }          static void* threadtoutine(void* args)         {             Thread<T>* self = (Thread<T>*)args;             self->Excute();             return nullptr;         }          // 启动线程         bool Start()         {             int n = pthread_create(&_tid, nullptr, threadtoutine, this);             if (n == 0)             {                 _stop = false;                 return true;             }             else return false;         }          // 分离线程         void Detach()         {             if (!_stop)             {                 pthread_detach(_tid);             }         }          // 等待线程结束         void Join()         {             if (!_stop)             {                 pthread_join(_tid, nullptr);             }         }          std::string name()         {             return _threadname;         }          // 停止线程         void Stop()         {             _stop = true;         }          ~Thread(){}     private:         pthread_t _tid;         std::string _threadname;         T _data;         func_t<T> _func;         bool _stop;     }; }  #endif 

testThread.cc

#include <iostream> #include <vector> #include "Thread.hpp" using namespace ThreadModule;  const int num = 10;  // 线程执行的任务 void print(int& cnt) {     while (cnt)     {         std::cout << "hello I am myself thread, cnt: " << cnt-- << std::endl;         sleep(1);     } }  int main() {     // 创建多线程     std::vector<Thread<int>> threads;     // 创建num个线程,每个线程执行print函数     for (int i = 0; i < num; ++i)     {         std::string name = "thread-" + std::to_string(i + 1);         threads.emplace_back(print, 10, name);     }      // 启动线程     for (auto& thread : threads)     {         thread.Start();     }      // 等待线程结束     for (auto& thread : threads)     {         thread.Join();         std::cout << "wait thread done, thread name: " << thread.name() << std::endl;     }      return 0; } 

结果:
在这里插入图片描述


未完待续

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!