C++ 多线程

1.1 并发、进程、线程的基本概念

1.1.1并发

两个或多个任务(独立的活动)同时发生:一个程序同时执行多个独立的任务。
单核CPU由操作系统调度,单时间片内只运行一个程序,进行任务切换,实现同时运行多个任务的假象,切换上下文有时间开销,切换回来要复原。
多核心CPU能够真正的实现并行执行任务(硬件并发)

1.1.2 线程

每个进程都有一个唯一的主线程,当运行可执行程序时,产生了一个进程后,主线程就随着进程启动。实际是进程的主线程来调用这个main函数的代码,线程是用来执行代码的,可以理解为一条代码的通路,每创建一个新的线程,同一时刻就可以多干一个不同的任务。
多线程不是越多越好,每个线程都需要一个独立的堆栈空间(1M),线程之间的切换需要保存很多中间状态,切换会耗费本该属于程序运行的时间。

1.1.3 并发的实现方法

两个或更多的任务同时发生
实现并发的手段:

  1. 多进程并发
    进程间通信:管道、文件、消息队列、共享内存、socket通信
  2. 多线程并发
    单个进程中创建多个线程,线程是轻量级的进程,每个线程都有自己独立的运行路径,但是同一进程中的所有线程共享进程的地址空间,全局变量、指针、引用都可以在线程之间传递。使用多线程的开销小于多进程。

共享内存带来数据一致性的问题。
多进程和多线程虽然可以同时使用,但是建议优先考虑多线程而不是多进程。

1.2 C++11新标准线程库

不同平台下 创建线程多线程函数:
windows:CreateThread(), _beginthread(), _beginthredexe()
Linux:pthread_create()
临界区,互斥量,以往多线程代码不能跨平台。

从C++11新标准,增加了对多线程的支持,意味着可移植性(跨平台)。

2. 线程启动、结束、创建多线程

多线程也从函数开始执行,到函数运行结束就结束,主线程执行完毕,整个进程也执行完毕。

2.1.1 使用函数创建线程

包含头文件 <thread>

thread是std标准库中的类,需要std::thread

thread mytobj(myprint); 创建线程,线程执行入口函数myprint,子线程熊myprint开始执行
join();加入,主线程阻塞,等待子线程执行完毕,主线程和子线程汇合,才会继续执行
detach();分离,主线程和子线程分离,各自执行各自程序代码。主线程不需要等待子线程执行完毕,一旦detach后,与这个主线程关联的thread对象就会失去和主线程的关联,此时子线程就会驻留在后台运行,由守护进程负责清理相关的资源。

一旦调用detach后不能再调用join,一般使用join
joinable()判断是否成功使用了join()或者detach(),返回true或者false

2.1.2使用类的可调用对象创建线程

class TA {
  public:
    TA() {
        m_i = 0;
        cout << "TA默认构造函数" << endl;
    }
    TA(int &val) : m_i(val) { cout << "TA有参构造函数" << endl; }
    TA(const TA &ta) : m_i(ta.m_i) { cout << "TA拷贝构造函数" << endl; }
    ~TA() { cout << "TA析构函数" << endl; }

    // 不能带参数
    void operator()() {
        cout << "子线程开始运行了" << endl;
        cout << "子线程结束运行了" << endl;
    }
    int m_i;
};

int main(){
    Ta ta;
    thread mytobj(ta);	// ta: 可调用对象
    mytobj.join();
    cout << "hello word" << endl;
}

对象实际是被复制到线程中去的,执行完主线程后,ta被销毁,但是复制到线程中的ta对象依然还是存在。

2.1.3使用lambda表达式创建线程

 // 使用lambda表达式
    auto mylambdat = [] {
        cout << "线程开始执行" << endl;
        cout << "线程接受执行" << endl;
        cout << "线程接受执行" << endl;
        cout << "线程接受执行" << endl;
        cout << "线程接受执行" << endl;
        cout << "线程接受执行" << endl;
    };
    thread mytobj(mylambdat);
    //mytobj.join();
    mytobj.detach();

to be continue....

posted @   Happinesspill  阅读(326)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示