搜索

C++ 多线程


发布时间: 2022-11-24 17:36:06    浏览次数:9 次

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....

免责声明 C++ 多线程,资源类别:文本, 浏览次数:9 次, 文件大小:-- , 由本站蜘蛛搜索收录2022-11-24 05:36:06。此页面由程序自动采集,只作交流和学习使用,本站不储存任何资源文件,如有侵权内容请联系我们举报删除, 感谢您对本站的支持。 原文链接:https://www.cnblogs.com/happinesspills/p/16784686.html