波奇学Linux:

死锁

一组进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放资源,而处于一种永久等待的状态

进程一占有资源A不释放,进程二占有资源B不释放,进程一申请资源B,进程二申请资源A,两个进程都属于阻塞状态

形成死锁的条件:

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

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

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

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

同步:保证数据安全(实现锁的状态下)的情况下,我们的线程访问有一定顺序性

线程之间的对共享资源的访问有一定的顺序,如线程一发送数据后,发送信号到线程二,线程二再访问获取数据,实现线程一,二这样的访问顺序

其中这个信号叫条件变量决定线程挂起或者访问

在Linux系统中条件变量的接口

pthread_cond_destroy: 销毁变量

pthread_cond_init: 创建临时变量

pthread_cond_broadcast:唤醒所有线程

pthread_cond_signal: 唤醒一个线程


int cnt=0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;void* Count(void* args)
{// 无符号整型uint64_t number=(uint64_t)args;pthread_detach(pthread_self()); //进程结束自动脱离不需要等待std::cout<<"thread-"<<number<<"create success"<<std::endl;while(true){pthread_mutex_lock(&mutex); //资源加锁pthread_cond_wait(&cond ,&mutex); // pthread_cond_wait让线程等待时,会自动释放锁!std::cout<<"pthread: "<<number<<" wake "<<", cnt"<<cnt++<<std::endl;pthread_mutex_unlock(&mutex);}
}
int main()
{for( uint64_t i=0;i<5;i++){pthread_t tid;pthread_create(&tid,nullptr, Count,(void*)i);}std::cout<<"main thread ctrl begin: "<<std::endl;while(true) {sleep(1);pthread_cond_signal(&cond);//唤醒在cond等待队列中的一个等待线程,默认是第一个}return 0;
}

上面的代码没有判断而是让代码直接休眠,让主线程唤醒来决定哪个线程代码运行 

实际上可以加入if判断句子

CP 问题(consumer producter)生产者-消费模型

代码实现BlockQueue模型

BlockQueue.hpp

#include<iostream>
#include<queue>
#include<pthread.h>template <class T>
class BlockQueue
{
public:BlockQueue(int defaultcap=50){std::cout<<"Init BlockQueue"<<std::endl;pthread_mutex_init(&mutex_,nullptr);pthread_cond_init(&cond_,nullptr);pthread_cond_init(&pond_,nullptr);maxcap_=50;low_water_=maxcap_/3;high_water_=maxcap_*2/3;}T pop(){pthread_mutex_lock(&mutex_);if(q_.size()==0){// 申请锁成功,发现队列为空了,释放锁,这个线程挂起pthread_cond_wait(&cond_,&mutex_);}// 队列没满T out=q_.front();q_.pop();if(q_.size()<low_water_) pthread_cond_signal(&pond_); //生产满了会自动挂起,此时到了low_water_会把挂起的线程投入生产pthread_mutex_unlock(&mutex_);return out;}void push(const T& in){// std::cout<<"run push function"<<std::endl;//加锁确认只有一个生产者输入pthread_mutex_lock(&mutex_);if(q_.size()==maxcap_){// std::cout<<"线程已满"<<std::endl;// 申请锁成功,发现队列满了,释放锁,这个线程挂起,pthread_cond_wait(&pond_,&mutex_);}// 队列没满// std::cout<<"push value"<<std::endl;q_.push(in);//发送信号,唤醒等待的线程if(q_.size()>high_water_) pthread_cond_signal(&cond_); //当数量较多时,把挂起的消费线程唤醒pthread_mutex_unlock(&mutex_);}~BlockQueue(){pthread_mutex_destroy(&mutex_);pthread_cond_destroy(&cond_);pthread_cond_destroy(&pond_);}
private:std::queue<T> q_; //共享资源int maxcap_;    //极值pthread_mutex_t mutex_; //锁pthread_cond_t cond_; pthread_cond_t pond_;//共享变量int low_water_=0;int high_water_=0;
};

main.cc

#include "BlockQueue.hpp"
#include<unistd.h>
void* Consumer(void*args)
{//consumer获取数据BlockQueue<int> *bq=static_cast<BlockQueue<int>*>(args);while(true){int data=bq->pop();std::cout<<"消费了一个临时变量: "<<data<<std::endl;}
}
void*Productor(void*args)
{// production获取数据// std::cout<<"run function Productor"<<std::endl;BlockQueue<int> *bq=static_cast<BlockQueue<int>*>(args);int data=0;while(true){data++;bq->push(data);std::cout<<"生产一个数据"<<data<<std::endl;}
}
int main()
{BlockQueue<int> *bq=new BlockQueue<int>();pthread_t c,p;// 只有两个线程,一个访问,一个生产pthread_create(&c,nullptr,Consumer,bq);pthread_create(&p,nullptr,Productor,bq);pthread_join(c,nullptr);pthread_join(p,nullptr);delete bq;return 0;
}

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

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

相关文章

算法时空复杂度分析:大O表示法

文章目录 前言大O表示法3个时间复杂度分析原则常见的时间复杂度量级空间复杂度参考资料 前言 算法题写完以后&#xff0c;面试官经常会追问一下你这个算法的时空复杂度是多少&#xff1f;&#xff08;好像作为一名算法工程师&#xff0c;我日常码代码的过程中&#xff0c;并没…

MySQL学习Day32——数据库备份与恢复

在任何数据库环境中&#xff0c;总会有不确定的意外情况发生&#xff0c;比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的&#xff0c;这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时&#xff0c;会出现主从服…

[JAVAEE]—进程和多线程的认识

文章目录 什么是线程什么是进程进程的组成什么是pcb 进程概括线程线程与进程的关系线程的特点 创建线程创建线程方法创建线程的第二种方法对比 其他的方式匿名内部类创建线程匿名内部类创建Runable的子类lambda表达式创建一个线程 多线程的优势 什么是线程 什么是进程 首先想…

C++_day3:构造函数、析构函数、拷贝构造函数

1.设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 程序代码&#xff1a; #include <iostream>…

行业认可 | 海云安上榜《2024年网络与信息安全行业全景图》多个领域

近日&#xff0c;深圳市网络与信息安全行业协会正式发布《2024年网络与信息安全行业全景图》。海云安凭借过硬的技术实力及成熟的网络与信息安全产品及服务获得行业认可&#xff0c;入围6大类目共计17项细分领域。包括&#xff1a; 业务安全&#xff08;软硬件开发安全、人工智…

深入学习React开发:从基础到实战

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 React是一款流行的JavaScript库&#xf…

Seata 2.x 系列【6】微服务项目搭建

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 概述2. 数据库…

腾讯t-design 实现图片预览组件的显示和使用

腾讯t-design 发布了 下面介绍一个组件的使用 图片预览 <template><div><div class"tdesign-demo-image-viewer__base"><t-image-viewer :images"[img]"><template #trigger"{ open }"><div class"tde…

three.js 鼠标左右拖动改变玩家视角

这里主要用到了 一个方法 obj.getWorldDirection(); obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。 按下 W键前进运动&#xff1b; <template><div><el-container><el-main><div class"box-card-left…

基于Java的天然气工程运维系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程 12.2.2 流程 22.3 各角色功能2.3.1 系统管理员功能2.3.2 用户服务部功能2.3.3 分公司&#xff08;施工单位&#xff09;功能2.3.3.1 技术员角色功能2.3.3.2 材料员角色功能 2.3.4 安…

python基于flask考研学习交流系统30vy7附源码django

考研在线学习与交流平台根据实际情况分为前后台两部分&#xff0c;前台部分主要是让用户使用的&#xff0c;包括用户的注册登录&#xff0c;首页&#xff0c;课程信息&#xff0c;在线讨论&#xff0c;系统公告&#xff0c;后台管理&#xff0c;个人中心等功能&#xff1b;后台…

【数据结构与算法】排序

目 录 一.排序的概念及引用1.1 排序的概念1.2 常见的排序算法 二.常见排序算法的实现2.1 插入排序直接插入排序希尔排序( 缩小增量排序 ) 2.2 选择排序直接选择排序堆排序 2.3 交换排序冒泡排序快速排序快速排序优化&#xff1a;非递归实现快速排序 2.4归并排序2.4.3 海量数据的…