Linux 第三十五章

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

互斥锁

scp指令

线程加锁的本质

可重入VS线程安全(多执行流并发执行同一段代码时造成的数据不一致)

死锁

线程同步

生产者消费者模型

条件变量

pthread_cond_wait

pthread_cond_signal

pthread_cond_broadcast

事例:火车票抢购


互斥锁

创建全局的锁

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//创建全局的锁,用宏去初始化

创建局部的锁

pthread_mutex_t mutex;//创建局部锁的时候不用宏初始化
pthread_mutex_init(&mutex);//初始化
pthread_mutex_destroy(&mutex);//局部的锁,不用时要销毁

scp指令

scp指令是用于在Linux系统中进行文件传输的命令,

其语法如下:

scp [选项] [源文件] [目标文件]
常用选项包括:* -r:递归复制整个目录
* -P:指定端口号
* -p:保持源文件的修改时间、访问时间和权限信息
* -q:安静模式,不显示传输进度信息
示例用法:1. 从本地复制文件到远程服务器:
scp /path/to/local/file username@remotehost:/path/to/remote/directory2. 从远程服务器复制文件到本地:
scp username@remotehost:/path/to/remote/file /path/to/local/directory3. 从远程服务器复制整个目录到本地:
scp -r username@remotehost:/path/to/remote/directory /path/to/local/directory

线程加锁的本质

关于加锁的原则,一般原则:谁加锁,谁解锁

可重入VS线程安全(多执行流并发执行同一段代码时造成的数据不一致)

可重入函数是线程安全函数的一种

线程安全不一定是可重入的,而可重入函数则一定是线程安全的。

如果将对临界资源的访问加上锁,则这个函数是线程安全的,但如果这个重入函数若锁还未释放则会产生死锁,因此是不可重入的。

死锁

原因

1)当两个线程需要都需要两把锁,而它们每一个线程只有一把锁,此时就会导致死锁

2)当一个线程在加锁的时候,没有解锁,又去加锁,这样就会导致死锁

…….

死锁必要条件(产生死锁的时候,这四个条件一定是满足的)

互斥条件:一个资源每次只能被一个执行流使用

请求与保持条件:一个执行流因请求资源而阻塞时,对已获得的资源保持不放

不剥夺条件:一个执行流已获得的资源,在末使用完之前,不能强行剥夺

循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系

避免死锁

破坏死锁的四个必要条件

加锁顺序一致

避免锁未释放的场景

资源一次性分配

线程同步

线程同步的概念:

在临界资源使用安全的前提下,让多线程执行具有一定的顺序性——同步

互斥:能够保证资源的安全性

同步:能够较为充分使用我们的资源

生产者消费者模型

3种关系

生产者之间关系,互斥

消费者之间关系,互斥

生产者与消费者之间关系,互斥和同步

本质:就是用锁和条件变量,维护

2种角色

生产者,消费者——线程或者进程

1个交易场所

内存空间

生产者消费者模型提高了数据处理的能力

条件变量

创建条件变量

pthread_cond_t cond;

全局的条件变量初始化

cond=PTHREAD_COND_INITIALIZER

局部条件变量的初始化

Pthread_cond_init(&cond);

局部条件变量需要销毁

pthread_cond_destory(&cond);

pthread_cond_wait

pthread_cond_wait() 是 POSIX 线程库中的一个函数,用于线程间的条件变量同步。它需要与互斥锁(mutex)和条件变量(condition variable)一起使用。
函数原型如下:

int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);pthread_cond_wait() 的作用是让调用线程等待条件变量的满足。在调用该函数之前,
必须先使用 pthread_mutex_lock() 锁住一个互斥锁,以确保线程安全。
当条件变量满足时,pthread_cond_wait() 函数会解锁互斥锁并使线程进入等待状态,
直到被其他线程通过 pthread_cond_signal() 或 pthread_cond_broadcast() 唤醒。

使用示例:

#include <pthread.h>
// 全局互斥锁和条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void* thread_func(void* arg) {// 获取互斥锁pthread_mutex_lock(&mutex);// 等待条件变量满足pthread_cond_wait(&cond, &mutex);// 条件变量满足后的处理// 解锁互斥锁pthread_mutex_unlock(&mutex);return NULL;
}
int main() {pthread_t thread;// 创建线程pthread_create(&thread, NULL, thread_func, NULL);// 在某个时刻满足条件,并通知等待的线程pthread_mutex_lock(&mutex);pthread_cond_signal(&cond);pthread_mutex_unlock(&mutex);// 等待线程结束pthread_join(thread, NULL);return 0;
}

在上面的示例中,主线程通过 pthread_cond_signal() 唤醒等待的线程。当满足条件时,等待的线程会被唤醒并继续执行。注意,在调用 pthread_cond_wait() 之前必须加锁(pthread_mutex_lock()),并在条件满足后解锁(pthread_mutex_unlock())。

pthread_cond_signal

pthread_cond_signal() 是 POSIX 线程库中的一个函数,用于唤醒等待在条件变量上的一个线程。它会选择一个等待的线程,并通知该线程条件已经满足,使得该线程从等待状态恢复到运行状态。

函数原型如下:

int pthread_cond_signal(pthread_cond_t* cond);
pthread_cond_signal() 的作用是发送一个信号给等待在条件变量上的某个线程,
使其从等待状态返回。如果有多个线程等待在条件变量上,那么只有其中一个线程会被唤醒,
具体哪个线程被唤醒则不确定。

pthread_cond_broadcast

pthread_cond_broadcast() 是 POSIX 线程库中的一个函数,用于广播唤醒所有等待在条件变量上的线程。当条件满足时,可以使用 pthread_cond_broadcast() 函数来唤醒所有等待在该条件变量上的线程,让它们从等待状态返回到运行状态。
 

函数原型如下:

int pthread_cond_broadcast(pthread_cond_t* cond);
pthread_cond_broadcast() 的作用是向所有等待在条件变量上的线程发送信号,
使它们全部被唤醒。所有被唤醒的线程都会尝试重新获取互斥锁,并继续执行。

1.让线程在进行等待的时候,会自定释放锁

2.线程被唤醒的时候,是在临界区内唤醒的,当线程被唤醒的时候,线pthread_cond_wait返回的时候要重新申请并持有锁

3.当线程被唤醒的时候,重新申请并持有锁的本质是也要参与锁的竞争

单纯的互斥,能保证数据的安全,不一定合理高效!

事例:火车票抢购

test_cond

#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;pthread_cond_t cond=PTHREAD_COND_INITIALIZER;//条件变量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//锁int tickets=1000;void* threadroutine(void* args)
{string name=static_cast<const char*>(args);while(true){// sleep(1);pthread_mutex_lock(&mutex);//加锁if(tickets>0){cout<<name<<", get a ticket: "<<tickets--<<endl;usleep(100);}else{cout<<"没票了"<<name<<endl;pthread_cond_wait(&cond,&mutex);//让线程满足条件变量,才被唤醒//1.让线程在进行等待的时候,会自动释放锁//2.线程被唤醒的时候,是在临界区内唤醒的,当线程被唤醒的时候,线程pthread_cond_wait返回的时候//要重新申请并持有锁//3.当线程被唤醒的时候,重新申请并持有锁的本质是也要参与锁的竞争}pthread_mutex_unlock(&mutex);}
}//主线程
int main()
{pthread_t t1,t2,t3;pthread_create(&t1,nullptr,threadroutine,(void*)"thread - 1");pthread_create(&t2,nullptr,threadroutine,(void*)"thread - 2");pthread_create(&t3,nullptr,threadroutine,(void*)"thread - 3");sleep(5);//主线程5s之后,开始唤醒一个线程while(true){// sleep(1);// pthread_cond_signal(&cond);sleep(20);//休息20s再放一批票pthread_mutex_lock(&mutex);tickets+=1000;pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond);//让一个线程被唤醒,才后这个线程在去抢票}pthread_join(t1,nullptr);pthread_join(t2,nullptr);pthread_join(t3,nullptr);return 0;
}

火车票抢购,其中会同时出现多个人(线程)去抢购票,所有的抢票的过程一定要是原子的,所以需要加互斥锁。还有一个问题,在上面的抢票过程中,会在一段时间增加票的数量,但总不能让某一个人(线程)把这些票都抢光吧!所以就需要条件变量,当这次票完的时候,将这个线程阻塞住,只有被唤醒才可以继续参与抢票。

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes安装calico网络插件失败

今天啥也没干成&#xff0c;不想排版了。 接着昨天搭建k8s集群&#xff0c;安装calico插件&#xff0c;虚拟机一直卡。 # 在 master 节点上执行 # 下载 calico 配置文件&#xff0c;可能会网络超时 curl https://docs.tigera.io/archive/v3.25/manifests/calico.yaml -O # 修…

[svelte] 怎么引入fortawesome的icon样式

首先在项目的终端下执行以下命令 npm install fortawesome/fontawesome-free # 或者 yarn add fortawesome/fontawesome-free这样子可以把fontawsome的图标给下载到项目的对应文件中 一般都是在node_modules中 在fontawsome/fontawesome-free中就可以看到很多文件夹了 …

unapp写微信小程序封装水印相机组件怎么实现?

<template><view><!-- <cu-custom bgColor"bg-gradual-blue" :isBack"true"><block slot"backText">返回</block><block slot"content">编辑资料</block></cu-custom> --><…

Docker学习(10)搭建kubernetes集群

搭建kubernetes集群 1、官方部署方式&#xff1a; Minikube工具安装 Minikube是一种能够在计算机或者虚拟机(VM)内轻松运行单节点Kubernetes 集群的工具&#xff0c;可实现一键部署。这种方式安装的系统在企业中大多被当作测试系统使用。 使用yum安装 通过直接使用 epel-r…

三步在 vite 中配置 tailwindcss

前言 tailwindcss 是一个原子化的 css 工具&#xff0c;可以让你免于写 css&#xff0c;只写 html 即可原理&#xff1a;利用你写的 html 的 class 名称来生成 css 样式&#xff0c;理解为一个 postcss 插件或 loader 第一步&#xff1a;安装 tailwindcss npm i -D tailwind…

图片恢复的实用指南,为你拯救遗失的记忆!

随着科技的日新月异&#xff0c;我们的生活已被照片填满。它们记录着我们的喜怒哀乐&#xff0c;见证着每一个重要的时刻。但我们往往会因为各种原因将手机图片遗失&#xff0c;有什么方法可以恢复呢&#xff1f;本文将提供一份实用的图片恢复指南&#xff0c;帮助你找回那些遗…

山西大学化学化工学院朱凤祥教授简介

男&#xff0c;1989年出生&#xff0c;河南安阳人&#xff0c;2019年1月于山西大学化学化工学院任特聘教授&#xff0c;主要研究方向为有机催化&#xff0c;曾获国家自然科学基金资助&#xff08;2020-2023&#xff09;&#xff0c;迄今在国际高级杂志发表SCI论文20余篇。 200…

llama使用tutorial微调(windows版本)

Llama3-Tutorial/docs/assistant.md at main SmartFlowAI/Llama3-Tutorial GitHub 有一些命令需要修改 前期的安装还是要按照教程搞的 streamlit run ~/Llama3-Tutorial/tools/internstudio_web_demo.py \ ~/model/Meta-Llama-3-8B-Instruct 改为了 streamlit run .\Ll…

ArrayList和LinkedList的使用

ArrayList List<> list new ArrayList<>(); LinkedList

SQL注入漏洞常用绕过方法

SQL注入漏洞 漏洞描述 Web 程序代码中对于用户提交的参数未做过滤就直接放到 SQL 语句中执行&#xff0c;导致参数中的特殊字符打破了原有的SQL 语句逻辑&#xff0c;黑客可以利用该漏洞执行任意 SQL 语句&#xff0c;如查询数据、下载数据、写入webshell 、执行系统命令以及…

WPF使用ItemsControl显示Object的所有属性值

对于上位机开发&#xff0c;我们有时候有这样的需求&#xff1a;如何显示所有的IO点位&#xff1f;比如有10个IO点位&#xff0c;那我们要写10个TextBlock去绑定这10个点位的属性&#xff08;本文暂时不考虑显示的样式&#xff0c;当然也可以考虑&#xff09;&#xff0c;当点位…

springboot整合swagger,jpa遇到的问题

1.整合jpa&#xff0c;版本问题导致Archive for required library: ‘C:/Users/Administrator/.m2/repository/org/aspectj/aspectjweaver/1.8.13/aspectjweaver-1.8.13.jar’ in project ‘money-server’ cannot be read or is not a valid ZIP file money-server Build path…

Leetcode 257:二叉树的所有路径

给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 思路&#xff1a; 先编辑所有节点&#xff0c;记录每一个节点的路径&#xff1b; 判断当前节点是否为叶子节点&#xff0c;如果是&…

霍庭格TruPlasma MF 7100 7050电源现货50KW

霍庭格TruPlasma MF 7100 7050电源现货50KW

mysql json 数组怎么搜索

在MySQL中&#xff0c;可以使用JSON_CONTAINS函数来搜索JSON数组中的元素。这里有一个简单的例子&#xff1a; 假设有一个名为items的表&#xff0c;其中有一个名为attributes的列&#xff0c;包含JSON数组。 CREATE TABLE items (id INT AUTO_INCREMENT PRIMARY KEY,attribu…

SQLSERVER 怎样使查询不占锁

对一些相对不怎么敏感的数据&#xff0c;不需要太及时性的数据&#xff0c;不需要占锁。 要在SQL Server中执行查询而不占用锁&#xff0c;可以采取以下几个策略&#xff1a; 1、使用NOLOCK提示&#xff1a; 最直接但风险较高的方法是在查询中使用WITH (NOLOCK)提示。这样&am…

练习题(2024/5/16)

1轮转数组 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,…

【C语言深度解剖】:(11)函数指针、函数指针数组、指向函数指针数组的指针、回调函数

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》《精通C指针》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏…

AVDemo漏洞平台黑盒测试

信息收集 说明一下&#xff1a; 因为是本地的环境&#xff0c;端口这些就不扫描了&#xff0c; 还有这个是某个dalao写的平台&#xff0c;也就检测不到什么cms了&#xff0c; 信息收集&#xff0c;端口&#xff0c;cms这些是必做的&#xff0c; 首先&#xff0c;这里先简单的…

web3 ETF软件开发难点

开发一个涉及到 Web3 ETF&#xff08;Exchange-Traded Fund&#xff0c;交易所交易基金&#xff09;的软件可能会面临一些挑战和难点&#xff0c;特别是在整合 Web3 技术和金融服务方面。以下是一些可能的难点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&am…