IO——线程

1. 什么是线程

1.1概念

线程是一个轻量级的进程,为了提高系统的性能引入线程。
线程和进程都参与统一的调度。
在同一个进程中可以创建的多个线程, 共享进程资源。
(Linux里同样用task_struct来描述一个线程)

1.2进程和线程的区别

相同点:都为操作系统提供了并发执行能力
不同点
调度和资源:线程是系统调度的最小单位,进程是资源分配的最小单位
地址空间方面:同一个进程创建的多个线程共享该进程的资源;进程的地址空间相互独立
通信方面:线程通信相对简单,只需要通过全局变量可以实现,但是需要考虑临界资源访问的问题;进程通信比较复杂,需要借助进程间的通信机制(借助3g-4g内核空间)
安全性方面:线程安全性差一些,当进程结束时会导致所有线程退出;进程相对安全

不同情况下的使用
对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
资源的保护管理要求不是很高,但要求效率高、速度快的
高并发环境时,需要频繁创建、销毁或切换时使用多线程。

1.3 线程资源

共享的资源:可执行的指令、静态数据、进程中打开的文件描述符、信号处理函数、当前工作目录、用户ID、用户组ID
私有的资源:线程ID (TID)、PC(程序计数器)和相关寄存器、堆栈(局部变量, 返回地址)、错误号 (errno)、信号掩码和优先级、执行状态和属性

2. 函数接口

2.1创建线程:pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                                void *(*start_routine) (void *), void *arg);
功能:创建线程
参数:       thread:线程标识
            attr:线程属性, NULL:代表设置默认属性
            start_routine:函数名:代表线程函数(自己写的)
            arg:用来给前面函数传参
返回值:成功:0
      失败:错误码
      
编译的时候需要加 -pthread 链接动态库

2.2退出线程:pthread_exit

void  pthread_exit(void *value_ptr) 
功能:用于退出线程的执行
参数:value_ptr:线程退出时返回的值

2.3回收线程资源

int  pthread_join(pthread_t thread,  void **value_ptr) 
    功能:用于等待一个指定的线程结束,阻塞函数
参数:thread:创建的线程对象,线程ID
     value_ptr:指针*value_ptr指向线程返回的参数, 一般为NULL
返回值:成功 : 0
    失败:errno

int pthread_detach(pthread_t thread);
功能:让线程结束时自动回收线程资源,让线程和主线程分离,非阻塞函数
参数:thread:线程ID
非阻塞式的,例如主线程分离(detach)了线程T2,
那么主线程不会阻塞在pthread_detach()pthread_detach()会直接返回,线程T2终止后会被操作系统自动回收资源
(线程T2的结果无法返回,所以必要时不能使用detach,让主线程结束)

3. 同步

3.1概念

同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情
(异步:异步则反之,并非一定需要一件事做完再做另一件事。)

3.2 同步机制

通过信号量实现线程间同步。
信号量:通过信号量实现同步操作;由信号量来决定线程是继续运行还是阻塞等待.
信号量代表某一类资源,其值表示系统中该资源的数量:
信号量的值>0,表示有资源可以用, 可以申请到资源,
信号量的值<=0, 表示没有资源可以通用, 无法申请到资源, 阻塞.
信号量还是一个受保护的变量,只能通过三种操作来访问:初始化、P操作(申请资源)、V操作(释放资源)

sem_init: 信号量初始化
sem_wait: 申请资源,P操作, 如果没有资源可以用, 阻塞,-1
sem_post: 释放资源,V操作, 非阻塞 +1

3.3函数接口

int  sem_init(sem_t *sem,  int pshared,  unsigned int value)  
    功能:初始化信号量   
参数:sem:初始化的信号量对象
    pshared:信号量共享的范围(0: 线程间使用   非0:1进程间使用)
    value:信号量初值
返回值:成功 0
    失败 -1

int  sem_wait(sem_t *sem)  
    功能:申请资源  P操作 
参数:sem:信号量对象
返回值:成功 0
    失败 -1
注:此函数执行过程,当信号量的值大于0时,表示有资源可以用,则继续执行,同时对信号量减1;当信号量的值等于0时,表示没有资源可以使用,函数阻塞
      (阻塞) 
int  sem_post(sem_t *sem)   
    功能:释放资源  V操作      
参数:sem:信号量对象
返回值:成功 0
    失败 -1
    注:释放一次信号量的值+1,函数不阻塞

4. 互斥

4.1概念

互斥:多个线程在访问临界资源时,同一时间只能一个线程访问
临界资源:一次仅允许一个线程使用的资源
临界区:指的是一个访问共享资源的程序片段
互斥锁:通过互斥锁可以实现互斥机制,主要用来保护临界资源,每个临界资源都由一个互斥锁来保护,线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止。

pthread_mutex_init
pthread_mutex_lock
pthread_mutex_unlock

4.2函数接口

int  pthread_mutex_init(pthread_mutex_t  *mutex, pthread_mutexattr_t *attr)  
功能:初始化互斥锁  
参数:mutex:互斥锁
    attr:  互斥锁属性  //  NULL表示缺省属性
返回值:成功 0
      失败 -1

int  pthread_mutex_lock(pthread_mutex_t *mutex)   
功能:申请互斥锁     
参数:mutex:互斥锁
返回值:成功 0
      失败 -1
注:和pthread_mutex_trylock区别:pthread_mutex_lock是阻塞的;pthread_mutex_trylock不阻塞,如果申请不到锁会立刻返回

int  pthread_mutex_unlock(pthread_mutex_t *mutex)   
功能:释放互斥锁     
参数:mutex:互斥锁
返回值:成功 0
      失败 -1

int  pthread_mutex_destroy(pthread_mutex_t  *mutex)  
功能:销毁互斥锁     
参数:mutex:互斥锁

补充:死锁

是指两个或两个以上的进程或线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
死锁产生的四个必要条件
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
注意:当上述四个条件都成立的时候,便形成死锁。
当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

5. 条件变量

条件变量用于在线程之间传递信号,以便某些线程可以等待某些条件发生。当某些条件发生时,条件变量会发出信号,使等待该条件的线程可以恢复执行。
一般和互斥锁搭配使用,实现同步机制

pthread_cond_init(&cond,NULL);	//初始化条件变量
使用前需要上锁:
pthread_mutex_lock(&lock);			 //上锁
判断条件
pthread_cond_wait(&cond, &lock);      //阻塞等待条件产生,没有条件产生时阻塞,同时解锁,当条件产生时结束阻塞,再次上锁
pthread_cond_signal(&cond);		//产生条件,不阻塞
pthread_cond_destroy(&cond);		//销毁条件变量
注意: 必须保证让pthread_cond_wait先执行,pthread_cond_signal再产生条件

为什么pthread_cond_wait前要加互斥锁
防止调用 pthread_cond_wait之前其他线程改变条件,从而发生错乱。
linux线程间同步有几种方式?

  1. 互斥锁(Mutex): 互斥算是一种特殊的同步。使用互斥锁可以确保同一时间只有一个线程可以访问共享资源。当一个线程进入临界区时,会锁定互斥锁,阻止其他线程进入该区域,直到该线程完成操作并释放锁。
  2. 信号量(Semaphore): 信号量用于控制对有限数量的资源的访问。它们是一种计数器,可以对其进行递增或递减操作。当信号量值为零时,线程必须等待,直到另一个线程递增该信号量。
  3. 条件变量(Condition Variable) : 条件变量用于在线程之间传递信号,以便某些线程可以等待某些条件发生。当某些条件发生时,条件变量会发出信号,使等待该条件的线程可以恢复执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/560077.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开源Windows12网页版HTML源码

源码介绍 开源Windows12网页版HTML源码&#xff0c;无需安装就能用的Win12网页版来了Windows12概念版&#xff08;PoweredbyPowerPoint&#xff09;后深受启发&#xff0c;于是通过使用HTML、CSS、js等技术做了这样一个模拟板的Windows12系统&#xff0c;并已发布至github进行…

jvm-接口调用排查

问题描述 线上碰到个问题&#xff0c;某个接口调用时间特别长&#xff0c;线上调用接口直接报gateway time out 分析处理 1、先关闭该功能 &#xff08;该功能是非核心功能&#xff09; 2、本地起服务连环境排查&#xff0c;发现本地正常。并且线上其他接口正常&#xff0c;…

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SA-BP模拟退火算法优化BP神经网络多变量回归预测&#xff0…

Ansible初识以及安装

1. Ansible应用简述&#xff1a; Ansible基于python语言实现&#xff0c;由Paramiko和PyYAML两个关键模块构建。具有独特的设计理念&#xff1a; 1&#xff09;安装部署简单 2&#xff09;管理主机便捷&#xff0c;支持多主机并行管理 3&#xff09;避免在被管理主机上安装客户…

【GitBlit】Windows搭建Git服务器详细教程

前言 如果公司或个人想在 Windows 环境下搭建私有的 Git 服务器&#xff0c;那么这个开源的 GitBlit 是一个不错的选择。 Gitblit 是一个开源纯 Java 的用于管理、查看和服务 Git 存储库。它是一个小型的托管集中式存储库工具。支持 SSH、HTTP 和 GIT 协议&#xff0c;开箱即…

通过PyCharm平台开发Django应用程序

学会使用命令行工具开发Django应用程序是基础&#xff0c;不过更多的时候还是要借助平台开发工具。目前&#xff0c;最好的Django应用程序开发工具就是jetBrains公司推出的PyCharm平台了。 借助PyCharm开发平台&#xff0c;可以极大提高开发Django应用程序的效率&#xff0c;同…

静态成员与友元,内部类初识

一.静态成员 1.静态成员变量 &#xff08;1&#xff09;定义&#xff1a; 类的定义中以静态声明的变量 &#xff08;2&#xff09;写法&#xff1a; static 变量声明 &#xff08;3&#xff09;注意&#xff1a; 静态成员变量不在对象中&#xff0c;在静态区&#xff0c…

从OWASP API Security TOP 10谈API安全

1.前言 应用程序编程接口&#xff08;API&#xff09;是当今应用驱动世界创新的一个基本元素。从银行、零售、运输到物联网、 自动驾驶汽车、智慧城市&#xff0c;API 是现代移动、SaaS 和 web 应用程序的重要组成部分&#xff0c;可以在面向客 户、面向合作伙伴和内部的应用程…

Xinstall:实现注册后自动绑定,提升用户体验

在移动互联网时代&#xff0c;App的注册与绑定流程对于用户体验至关重要。繁琐的注册步骤和手动绑定操作往往会让用户望而却步&#xff0c;导致用户流失。为了解决这一问题&#xff0c;Xinstall品牌推出了注册后自动绑定功能&#xff0c;极大提升了用户体验。 Xinstall的自动…

手写Java设计模式之抽象工厂模式,附源码解读

接上篇&#xff0c;抽象工厂模式将汽车的一些属性可以抽象出来&#xff0c;可以理解为给不同汽车品牌生成时加上不同的特性&#xff0c;如颜色等&#xff0c;具体代码如下&#xff1a; 引入颜色接口&#xff1a; public interface Colour {void fill(); }将颜色与汽车生成品牌…

线性代数基础2矩阵

矩阵是什么 矩阵就是二维数组&#xff0c;下面是一个 m 乘 n 的矩阵&#xff0c;它有 m 行&#xff0c;n 列&#xff0c;每行每列上面都有元素&#xff0c;每个元素都有行标i 和列标 j&#xff0c; a ij 。简称m n矩阵&#xff0c;记作&#xff1a; 注意a11的索引是 A[0,0]。…

Redis入门到通关之数据结构解析-RedisObject

文章目录 ☃️概述☃️源码 ☃️概述 RedisObject 是 Redis 中表示数据对象的结构体&#xff0c;它是 Redis 数据库中的基本数据类型的抽象。在 Redis 中&#xff0c;所有的数据都被存储为 RedisObject 类型的对象。 RedisObject 结构体定义如下&#xff08;简化版本&#xf…

网络流问题详解

1. 网络最大流 1.1 容量网络和网络最大流 1.1.1 容量网络 设 G(V, E)是一个有向网络&#xff0c;在 V 中指定了一个顶点&#xff0c;称为源点&#xff08;记为 Vs&#xff09;&#xff0c;以及另一个顶点&#xff0c;称为汇点&#xff08;记为 Vt&#xff09;&#xff1b;对…

【ds】替换空格

用‘%20’替换空格 var replaceBlank (charArr)> {if (!charArr || charArr.length 0) return var len charArr.lengthlet spaceLen 0for (let i 0; i < len; i) {if (charArr[i] ) {spaceLen}}var extraLen spaceLen * 2 // -> 20% 每一个空格需要增加2个ch…

大型网站系统架构演化实例_4.数据库读写分离

1.数据库读写分离 网站在使用缓存后&#xff0c;使对大部分数据读操作访问都可以不通过数据库就能完成&#xff0c;但是仍有一部分操作&#xff08;缓存访问不命中、缓存过期&#xff09;和全部的写操作都需要访问数据库&#xff0c;在网站的用户达到一定规模后&#x…

Python-VBA函数之旅-getattr函数

目录 一、getattr函数的常见应用场景&#xff1a; 二、getattr函数使用注意事项&#xff1a; 1、getattr函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://blog.csdn.net/ygb_1024?spm1010.21…

大模型应用开发基础

AGI 时代&#xff0c;AI 无处不在&#xff0c;形成新的社会分层&#xff1a; AI 使用者&#xff0c;使用别人开发的 AI 产品AI 产品开发者&#xff0c;设计和开发 AI 产品基础模型相关&#xff0c;训练基础大模型&#xff0c;或为大模型提供基础设施 越向下层&#xff0c;重要…

ISP图像处理pipeline简介2

上一篇文章介绍了ISP pipeline中的3A和镜头传感器校正。现在继续介绍pipeline中的其它流程。 上一篇文章主要讲了镜头&#xff0c;sensor相关的处理流程&#xff0c;pipeline接下来的一步是颜色插值。 sensor直接输出的图片是raw格式&#xff0c;需要经过isp处理之后才是平时常…

2024燃动智火-业务视角的中国企业AI+学习发展报告

来源&#xff1a;新华三 学习型组织的数字化转型是众多企业关注的焦点&#xff0c;数字战略需要人才升级&#xff0c;数字 化学习加速人才培养。AI 技术在学习中的运用&#xff0c;为企业学习型组织的数字化转型插 上了飞翔的翅膀。这份报告解码了AI 时代企业的学习发展&#…

k8s安装记录

k8s安装记录 如无特别说明&#xff0c;则该步操作指在所有的机器上执行&#xff01;&#xff01;&#xff01; 如无特别说明&#xff0c;则该步操作指在所有的机器上执行&#xff01;&#xff01;&#xff01; 如无特别说明&#xff0c;则该步操作指在所有的机器上执行&#…
最新文章