如何理解C++11中的多线程(了解)
#include <iostream>
#include <unistd.h>
#include <thread>void thread_run()
{while (true){std::cout << "我是新线程..." << std::endl;sleep(1);}
}
int main()
{// 任何语言需要在Linux上实现多线程,必定是要用到pthread库的!// 如何看待C++11中的多线程呢?// 本质上就是对pthread库的封装std::thread t1(thread_run);while (true){std::cout << "我是主线程..." << std::endl;sleep(1);}t1.join();return 0;
}
封装代码
封装代码写在Thread.hpp 文件当中,未来想使用封装好的线程就直接包含Thread.hpp文件即可!
// hpp 表示header only 开源代码
// 将函数定义和声明放在一起#pragma once#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <cassert>// 先声明 要使用
class Thread;// 上下文,当大号结构体使用
// 用Context来处理静态方法调用不了成员变量的问题
class Context
{
public:Thread *this_;void *args_;public:Context() : this_(nullptr), args_(nullptr){}~Context(){}
};// 对线程做封装,以后就不需要总去调用原生库的接口了
class Thread
{
public:// using func_t = std::function<void*(void*)>; -- C++11 智能指针typedef std::function<void *(void *)> func_t;const int num = 1024;// "void *(Thread::*)(void *args)" 类型的实参与 "void *(*)(void *)" 类型的形参不兼容C/C++(167) -- 报错// 为啥呢? -- 因为start_routine是类内的成员函数,有缺省参数this指针// void* start_routine(void* args)// {// return func_(args);// }// 在类内创建线程 这样就没有this指针了static void *start_routine(void *args){// 但是没有this指针// 静态方法不能调用成员方法或成员变量// return func_(args);// 可以采用友元,或者public成员的方式 这里不用!!// 将args强转成Context的指针Context *ctx = static_cast<Context*>(args);// 调用run方法 -- 将方法从静态中剥离出来void* ret = ctx->this_->run(ctx->args_);delete ctx;return ret;}// 构造函数Thread(func_t func, void *args = nullptr, int number = 0) : func_(func), args_(args){char buffer[num];snprintf(buffer, sizeof buffer, "thread-%d", number);name_ = buffer;// 加上ContextContext* ctx = new Context();ctx->this_ = this;ctx->args_ = args_;// 将ctx传过去int n = pthread_create(&tid_, nullptr, start_routine, ctx);//int n = pthread_create(&tid_, nullptr, start_routine, args);assert(n == 0);(void)n;}// 线程等待void join(){int n = pthread_join(tid_, nullptr);assert(n == 0);(void)n;}void *run(void *args){return func_(args);}// 析构~Thread(){// do nothing}private:// 自定义线程名 方便观察(不需要通过观察tid)// 末尾加_ 将成员变量和参数做区分std::string name_;pthread_t tid_;// 线程执行任务func_t func_;// 获取参数void *args_;
};
使用封装
#include "Thread.hpp"
#include <memory>
#include <unistd.h>void *thread_run(void *args)
{std::string work_type = static_cast<const char *>(args);while (true){std::cout << "我是一个新线程,我正在做:" << work_type << std::endl;sleep(1);}
}int main()
{std::unique_ptr<Thread> thread1(new Thread(thread_run, (void *)"hellothread", 1));std::unique_ptr<Thread> thread2(new Thread(thread_run, (void *)"countthread", 2));std::unique_ptr<Thread> thread3(new Thread(thread_run, (void *)"printthread", 3));std::unique_ptr<Thread> thread4(new Thread(thread_run, (void *)"iothread", 4));thread1->join();thread2->join();thread3->join();thread4->join();return 0;
}