C++并发编程(1):基本概念、线程管控

学习视频与书籍

学习视频

c++11并发与多线程视频课程

学习书籍

我本来打算去图书馆借《C++新经典》的,偶然发现这本书,如获至宝

在这里插入图片描述

  • 书挺新的,我看译者序是21年10月
  • 这本书挺贵的,后面写着139.80,大家还是去图书馆借吧
  • 作为基础与入门我觉得看前5章应该就够了

基本概念

C++11并发与多线程笔记(1) 并发基本概念及实现,进程、线程基本概念

进程

运行起来的可执行程序

线程

  • 每个进程都有一个主线程
  • 主线程随着进程的启动而启动
  • 同一个进程可以通过代码创建其它线程
  • 线程用来执行代码,可以理解为代码的执行通路

在这里插入图片描述

  • 线程的存在使得可以在同一时刻干多个不同的事

💡 线程并不是越多越好,每个线程,都需要一个独立的堆栈空间(大约1M),线程之间的切换要保存很多中间状态,切换也会耗费本该属于程序运行的时间

在这里插入图片描述

并发

多进程并发

  • 比如账号服务器一个进程,游戏服务器一个进程
  • 服务器进程之间存在通信(同一个电脑上:管道,文件,消息队列,共享内存;不同电脑上:socket通信技术)

多线程并发

  • 线程像是轻量级的进程。每个进程有自己独立的运行路径,但一个进程中的所有线程共享地址空间(共享内存),全局变量、全局内存、全局引用都可以在线程之间传递,所以多线程开销远远小于多进程
  • 多进程并发和多线程并发可以混合使用,但建议优先考虑多线程技术

线程管控

线程的基本管控

基本操作

  • 包含头文件
  • 构造std::thread实例
  • 向该实例提供可调用对象

💡 新线程必须包含入口函数

可调用函数对象包括:

  • 函数
  • 函数指针
  • lambda表达式
  • bind创建的对象
  • 函数对象(仿函数)

实例

#include <thread>
#include <iostream>

using namespace std;

class MyPrint
{
public:
    MyPrint()
    {
        cout << "默认构造函数...." << endl;
    }
    void operator()()
    {
        cout << "线程开始执行!" << endl;

        cout << "线程结束执行!" << endl;
    }
    ~MyPrint()
    {
        cout << "析构函数...." << endl;
    }
};

int main()
{
    // MyPrint myprint;
    thread my_thread{MyPrint()};
    if(my_thread.joinable())
    {
        cout << "Thread joinable...." << endl;
        // my_thread.join();
        my_thread.detach();
    }
    else
    {
        cout << "Unable to join...." << endl;
    }

    cout << "Life is for coding!" << endl;
    
    return 0;
}

注意点:

  • 将函数对象传递给thread构造函数时,实际调用了类的默认拷贝构造函数,内存中多了一份数据
  • 类必须重载函数操作符( ),才可作为参数传递给thread对象
  • 传递匿名对象是要用大括号
  • join( )阻塞主线程,主线程等待所有次线程完成后运行后续语句
  • detach( )主线程、次线程各走各的,主线程结束后次线程在后台继续运行但无显示和输出
  • 使用join( )和detach( )前先用joinable( )进行判断

变量生存期问题

次线程可能会访问外部数据,如局部变量等

若是函数内的局部变量,函数运行结束局部变量即销毁,此时访问该变量会产生未定义行为

可以理解为野指针或浅拷贝的问题

在这里插入图片描述

在这里插入图片描述

解决方法:

  1. 将数据复制到新线程内部,而不是共享数据
  2. 在函数中汇合新线程,确保函数退出前新线程执行完毕

对‘pthread_create’未定义的引用

我是在Linux下编程,没用gcc进行编译,写的CMakeLists.txt,在build目录下make时报错

对‘pthread_create’未定义的引用

gcc编译报错的解决

对pthread_create未定义的引用

因为还未详细用到pthread,先列出以供后续了解

pthread与std::thread的区别与应用

C++多线程pthread和thread

应该是我CMakeLists.txt写的不对,参考

c++多线程 CMakeLists设置

我的CMakeLists.txt更改如下:

cmake_minimum_required(VERSION 2.8)
project(Cplus_learning)

SET(CMAKE_CXX_COMPILER "g++") 

#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 

# add_subdirectory(src bin)

add_executable(thread_01 src/thread_01.cpp)

可以正常编译并运行

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Prejudices

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值