进程与线程学习心得

2023-05-16

一、进程与线程的区别

1.进程是操作系统进行资源调度和分配的基本单位,线程是操作系统可执行的最小调度和分配单位

2.一个线程属于一个进程,一个进程可以有多个线程

3.一个进程崩溃不影响其他进程,但是一个线程崩溃会让进程崩溃

4.进程在执行过程中有独立的存储单元,而线程之间共享进程的内存

  1. 进程之间切换系统开销大,而线程之间切换开销比进程小

二、多线程

线程:

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,进程包含一个或者多个线程。进程可以理解为完成一件事的完整解决方案,而线程可以理解为这个解决方案中的的一个步骤,可能这个解决方案就这只有一个步骤,也可能这个解决方案有多个步骤。

多线程:

多线程是实现并发(并行)的手段,并发(并行)即多个线程同时执行,一般而言,多线程就是把执行一件事情的完整步骤拆分为多个子步骤,然后使得这多个步骤同时执行。

C++多线程:(简单情况下)C++多线程使用多个函数实现各自功能,然后将不同函数生成不同线程,并同时执行这些线程(不同线程可能存在一定程度的执行先后顺序,但总体上可以看做同时执行)。

三、线程创建方式

#include <iostream>
#include <thread>
using namespace std; 
void show(){
} 
int main(){
    thread my_thread(show,1);
    my_thread.join();
    return 0;
}

join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续。my_thread.join();,即该语句所在的线程(该语句写在main()函数里面,即主线程内部)暂停,等待指定线程(指定线程为my_thread.join();执行结束后,主线程再继续执行。my_thread.join();

四、线程互斥锁

lock()与unlock()

#include<iostream>
#include<thread>
#include<mutex>
using namespace std;
mutex m;//实例化m对象,不要理解为定义变量
void th1(int a)
{
    m.lock();
    cout << "th1函数正在改写a" << endl;
    cout << "原始a为" << a << endl;
    cout << "现在a为" << a + 100 << endl;
    m.unlock();
}

void th2(int a)
{
    m.lock();
    cout << "th22函数正在改写a" << endl;
    cout << "初始始a为" << a << endl;
    cout << "现在a为" << a + 200<< endl;
    m.unlock();
}
int main()
{
    int a = 0;
    thread th1(proc1, a);
    thread th22(proc2, a);
    th1.join();
    th2.join();
    return 0;
}

lock_guard()

其原理是:声明一个局部的lock_guard对象,在其构造函数中进行加锁,在其析构函数中进行解锁。最终的结果就是:创建即加锁,作用域结束自动解锁。从而使用lock_guard()就可以替代lock()与unlock()。

include<iostream>
#include<thread>
#include<mutex>
using namespace std;
mutex m;//实例化m对象,不要理解为定义变量
void th1(int a)
{
    {
    lock_guard<mutex> g1(m);
    cout << "th1函数正在改写a" << endl;
    cout << "原始a为" << a << endl;
    cout << "现在a为" << a + 100 << endl;
    m.unlock();
    }//出了作用域自动解锁,不需要再调用unlock();
}

void th2(int a)
{
    lock_guard<mutex> g1(m);
    cout << "th2函数正在改写a" << endl;
    cout << "初始始a为" << a << endl;
    cout << "现在a为" << a + 200<< endl;
    m.unlock();
}
int main()
{
    int a = 0;
    thread th1(proc1, a);
    thread th22(proc2, a);
    th1.join();
    th2.join();
    return 0;
}

lock_gurad也可以传入两个参数,第一个参数为adopt_lock标识时,表示不再构造函数中不再进行互斥量锁定,因此此时需要提前手动锁定。

例如:

void th1()
{
m.lock();//手动锁定
lock_guard<mutex> g1(m,adopt_lock);//不需要加unlock()。
}

unique_lock:

unique_lock类似于lock_guard,只是unique_lock用法更加丰富,同时支持lock_guard()的原有功能。

使用lock_guard后不能手动lock()与手动unlock();使用unique_lock后可以手动lock()与手动unlock();

unique_lock的第二个参数,除了可以是adopt_lock,还可以是try_to_lock与defer_lock;

try_to_lock: 尝试去锁定,得保证锁处于unlock的状态,然后尝试现在能不能获得锁;尝试用mutx的lock()去锁定这个mutex,但如果没有锁定成功,会立即返回,不会阻塞在那里

defer_lock: 始化了一个没有加锁的mutex;

#include<iostream>
#include<thread>
#include<mutex>
using namespace std;
mutex m;
void proc1(int a)
{
    unique_lock<mutex> g1(m, defer_lock);//始化了一个没有加锁的mutex
    cout << "不拉不拉不拉" << endl;
    g1.lock();//手动加锁,注意,不是m.lock();注意,不是m.lock();注意,不是m.lock()
    cout << "proc1函数正在改写a" << endl;
    cout << "原始a为" << a << endl;
    cout << "现在a为" << a + 2 << endl;
    g1.unlock();//临时解锁
    cout << "不拉不拉不拉"  << endl;
    g1.lock();
    cout << "不拉不拉不拉" << endl;
}//自动解锁

void proc2(int a)
{
    unique_lock<mutex> g2(m,try_to_lock);//尝试加锁,但如果没有锁定成功,会立即返回,不会阻塞在那里;
    cout << "proc2函数正在改写a" << endl;
    cout << "原始a为" << a << endl;
    cout << "现在a为" << a + 1 << endl;
}//自动解锁
int main()
{
    int a = 0;
    thread proc1(proc1, a);
    thread proc2(proc2, a);
    proc1.join();
    proc2.join();
    return 0;
}
unique_lock所有权的转移

mutex m;
{  
    unique_lock<mutex> g2(m,defer_lock);
    unique_lock<mutex> g3(move(g2));//所有权转移,此时由g3来管理互斥量m
    g3.lock();
    g3.unlock();
    g3.lock();
}

condition_variable:

需要#include<condition_variable>;

wait(locker):在线程被阻塞时,该函数会自动调用 locker.unlock() 释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。另外,一旦当前线程获得通知(通常是另外某个线程调用 notify_* 唤醒了当前线程),wait() 函数此时再自动调用 locker.lock()。

notify_all():随机唤醒一个等待的线程

notify_once():唤醒所有等待的线程

五、线程池

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程与线程学习心得 的相关文章

  • C++ 库函数<string>示例

    最近在学C 43 43 自己整理了一部分C 43 43 库函数 lt string gt 的一些 函数 主要都是C 43 43 的 想到以后可能会用到 所以打算记录一下 方便自己也方便了大家 在啃这些函数的时候有很多借鉴之处 xff0c 在
  • 两台电脑间的串口通信

    目录 一 准备工作 二 实验过程 三 实验结果 一 准备工作 1 两台笔记本电脑 2 2个usb转串口模块 3 杜邦线若干 4 秒表 二 实验过程 两个串口线分别连接两台电脑 连线方式 xff1a 3V3 3V3 xff0c GND GND
  • c++ primer plus学习笔记(1)——基础知识

    本人还有一星期要开始期末考试了 xff0c 复习c 43 43 时顺便挖个坑 xff0c 之后会详细更新 目录 1 初识源代码 1 1 c 43 43 程序的产生 1 2 代码例 1 3 标记 空白 2 简单数据类型 2 1 变量名 2 2
  • C语言:sizeof和strlen计算字符串大小

    大家清楚 sizeof 和 strlen 的区别吗 xff1f sizeof是运算符 xff0c 确定的是字符所占空间大小 xff0c 参数可以有数组 指针 类型 对象 函数等 strlen是C语言的标准库函数 xff0c 确定是字符串的大
  • Python--爬虫--requests进阶,cookie/session模拟登录

    目录 一 原理 二 实际操作 三 结果 四 问题与总结 一 原理 以下内容为使用requests库发送请求 xff0c 使用cookie session模拟登录 xff08 并且登录时只需输入账号与密码 xff09 我们在使用搜索引擎访问网
  • linux系统移植U-boot与kernel的搭载流程(交互模式下)

    Linux系统移植四大部分 xff1a 搭建交叉开发环境 bootloader的选择和移植 本文选用bootloader下的U boot uImage的配置 编译与移植 根文件系统的制作 全部已完成 xff0c 本文只讲解 如何搭载这些东西
  • FreeRTOS任务创建、删除| FreeRTOS三

    目录 一 FreeRTOS任务创建与删除有关函数 1 1 创建 删除任务的API函数 1 1 1 动态创建任务 1 1 2 静态创建任务 1 1 3 删除任务 二 FreeRTOS任务创建与删除 xff08 动态方法 xff09 2 1 实
  • (学习)基于STM32的串口通信打印数据(HAL库+CubeMX)

    当我们在进行开发的时候 xff0c 通常需要将一些参数进行调整来达到效果 xff0c 这个时候就需要将单片机上的信息通过串口通信传送到PC机上来直观显示 一 基本的专有名词和原理介绍 USART xff1a 只能异步通信 USART xff
  • ROS通信——C++实现

    一 普通话题通信 创建功能包 xff1a catkin create pkg package roscpp rospy std msgs 创建发布者 xff1a include 34 ros ros h 34 include 34 std
  • ROS使用Python编写的步骤

    第一步 xff1a 和C 43 43 编写一样 xff0c 配置好工作空间 第二步 xff1a 在功能包下面建立一个scripts文件夹 第三步 xff1a 在scripts文件里面建立一个 py文件 第四步 编写python文件 注意 x
  • window的QT作为TCP客户端,ubuntu的python作为TCP服务端

    客户端 pro文件加入 QT 43 61 network mainwindow h ifndef MAINWINDOW H define MAINWINDOW H include lt QMainWindow gt include lt Q
  • RoboCom机器人大赛使用yolov5抽取20个随机图片进行人群识别

    目录 1 原理 2 思维流程 2 1 进行yolov5的环境搭建 2 1 1 在Linux的ubuntu环境anaconda的安装 2 1 2 Vscode的安装和配置 2 1 3 Github上面yolov5文件的下载 2 1 4 使用A
  • C语言实现字符串逆序、倒置字符串(字符串逆序问题的升级)

    一 字符串逆序 问题描述 xff1a 输入一个字符串str xff0c 将其内容颠倒过来 xff0c 并输出 数据范围0 lt len str lt 10000 输入描述 xff1a 输入一个字符串 xff0c 可以有空格 输出描述 xff
  • C语言实现“井字棋”游戏(三子棋)人机对弈

    井字棋游戏 xff1a 即三子棋 xff0c 英文名叫Tic Tac Tic xff0c 是一种在3 3格子上进行的连珠游戏 xff0c 和五子棋比较类似 xff0c 由于棋盘一般不画边线框 xff0c 格线排成井字故得名 题目分析 xff
  • C语言基础编程练习(精选例题+题解)

    目录 1 求最大公约数和最小公倍数 2 打印图形 3 质数因子 4 数字排序 5 十进制数转换为八进制数 xff08 进制转换 xff09 6 寻找完数 1 求最大公约数和最小公倍数 题目描述 xff1a 输入两个正整数m和n xff0c
  • C语言——实现“扫雷”小游戏(简易版)

    扫雷游戏想必我们都有玩过 xff0c 那么今天就用C语言来简单实现 扫雷 小游戏 xff01 目录 一 游戏规则 二 基本思路介绍 三 各功能代码实现 1 创建用户交互界面 2 初始化棋盘函数 3 埋雷函数 4 显示棋盘函数 5 排雷函数
  • linux驱动开发关于内核模块、设备模型、内存管理、模块参数介绍

    内核功能 多任务管理 内存管理 文件管理 网络协议栈 设备管理 设备驱动 我是分割线 一 内核开发特点 内核代码的运行时机 启动目标硬件应用程序调用系统调用硬件中断调用中断处理Linux内核和驱动间的接口 kABI 不稳定内核升级后 接口可
  • Java实现单链表及其基本操作

    目录 什么是单链表 xff1f 带头结点的单链表 不带头结点的单链表 模拟实现不带头结点的单链表 定义结点类 初始化 头插法创建单链表 尾插法创建单链表 打印单链表 单链表的查找 获取单链表的长度 按位置寻找前驱结点 单链表的插入 修改指定
  • 优化后的快速排序(详解)

    目录 快速排序 三数取中值分割法获得枢纽元 快速排序的主例程 直接插入排序代码 快速排序完整代码 快速排序 快速排序是实践中的一种快速的排序算法 xff0c 它的平均运行时间是O N log N xff0c 该算法之所以特别快 xff0c

随机推荐