Linux中经典的并发编程问题生产者和消费者

一,进程和线程区别

1,进程是程序的一次执行实例,是系统进行资源分配和调度的独立单位。进程具有独立的内存空间、系统资源以及独立的执行序列。每个进程都有其独立的进程控制块(PCB),用于描述进程的状态和相关信息。

2,线程是进程中的一个执行单元,是操作系统进行运算调度的最小单元。线程共享进程的内存空间和系统资源,有自己的执行序列,但没有独立的内存空间。线程之间可以通过共享内存等方式进行通信和同步。

3,进程中包含了线程,线程属于进程。一个进程可以包含多个线程,而每个线程都是进程的一部分。

二,线程互斥,同步方式

在Linux中,线程的互斥(互斥量)和同步(如条件变量、信号量、读写锁等)是多线程编程中非常重要的概念。这些机制帮助开发者避免数据竞争、死锁和其他并发问题。以下是Linux中常用的线程互斥和同步方式:

1,互斥量(Mutex)
互斥量用于保护对共享资源的访问,以确保一次只有一个线程可以访问该资源
在C/C++中,通常使用pthread_mutex_t类型表示互斥量,并通过pthread_mutex_init、pthread_mutex_lock、pthread_mutex_unlock等函数来初始化、锁定和解锁互斥量。

2,条件变量(Condition Variable)
条件变量与互斥量一起使用,允许线程等待某个条件成立后再继续执行。
当某个条件不满足时,线程可以使用条件变量将自己阻塞,并在条件满足时被唤醒
在C/C++中,使用pthread_cond_t类型表示条件变量,并通过pthread_cond_init、pthread_cond_wait、pthread_cond_signal等函数来初始化、等待和发送信号。

3,信号量(Semaphore)
信号量是一种更通用的同步机制,可以用于控制多个线程对共享资源的访问。
与互斥量不同,信号量允许多个线程同时访问资源,但会限制同时访问的线程数。
在Linux中,可以使用POSIX信号量(sem_t)或System V信号量(struct sembuf、semid_ds等)。

4,读写锁(Read-Write Lock)
读写锁允许多个线程同时读取共享资源,但只允许一个线程写入
这对于读操作远多于写操作的场景非常有用,因为它可以提高并发性能。
在C/C++中,可以使用pthread_rwlock_t类型表示读写锁,并通过pthread_rwlock_init、pthread_rwlock_rdlock、pthread_rwlock_wrlock等函数来初始化、读锁定和写锁定。

5, 自旋锁(Spinlock)
自旋锁是一种特殊的互斥量,当线程尝试获取锁失败时,它会在一个循环中持续尝试获取锁,而不是被阻塞
自旋锁适用于短时间的等待场景,因为它避免了线程切换的开销。但是,如果等待时间较长,自旋锁会浪费CPU资源。
在Linux内核编程中,自旋锁是一个常见的同步机制。

以上就是在Linux中常用的线程互斥和同步方式。在实际应用中,应根据具体场景选择合适的同步机制。

三,生产者和消费者原理

在Linux中,生产者和消费者问题是一个经典的并发编程问题。它描述了两个或多个进程(或线程)共享一个固定大小的缓冲区,并且按照生产者-消费者模式进行交互。生产者负责生成数据并放入缓冲区,而消费者则从缓冲区中取出数据进行处理。

以下是生产者和消费者问题的基本原理以及使用POSIX线程(pthreads)的C语言实现代码:

基本原理

1,共享缓冲区:有一个固定大小的缓冲区用于存储数据。
2,互斥访问:生产者和消费者需要互斥地访问缓冲区,以避免数据竞争。
3,同步机制:使用条件变量、信号量或其他同步机制来确保生产者在缓冲区满时不会继续生产,消费者在缓冲区空时不会继续消费。

C语言实现

以下是一个简单的生产者和消费者问题的C语言实现,使用了POSIX线程、互斥锁和条件变量:

#include <stdio.h>  
#include <stdlib.h>  
#include <pthread.h>  #define BUFFER_SIZE 10  int buffer[BUFFER_SIZE];  
int in = 0;  
int out = 0;  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;  
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;  void *producer(void *arg) {  for (int i = 0; i < 100; ++i) {  pthread_mutex_lock(&mutex);  // 等待缓冲区不满  while ((in + 1) % BUFFER_SIZE == out) {  pthread_cond_wait(&not_full, &mutex);  }  // 生产数据  buffer[in] = i;  printf("Produced: %d\n", buffer[in]);  in = (in + 1) % BUFFER_SIZE;  pthread_cond_signal(&not_empty); // 通知消费者  pthread_mutex_unlock(&mutex);  }  pthread_exit(NULL);  
}  void *consumer(void *arg) {  for (int i = 0; i < 100; ++i) {  pthread_mutex_lock(&mutex);  // 等待缓冲区不空  while (in == out) {  pthread_cond_wait(&not_empty, &mutex);  }  // 消费数据  int data = buffer[out];  printf("Consumed: %d\n", data);  out = (out + 1) % BUFFER_SIZE;  pthread_cond_signal(&not_full); // 通知生产者  pthread_mutex_unlock(&mutex);  }  pthread_exit(NULL);  
}  int main() {  pthread_t prod, cons;  pthread_create(&prod, NULL, producer, NULL);  pthread_create(&cons, NULL, consumer, NULL);  pthread_join(prod, NULL);  pthread_join(cons, NULL);  return 0;  
}

在这个例子中,生产者和消费者都是无限循环的,但为了简化,我们限制了它们各自只生产或消费100个数据项。注意,在实际应用中,你可能需要设置更复杂的退出条件。

这个代码使用了互斥锁(pthread_mutex_t)来保护对缓冲区的访问,并使用条件变量(pthread_cond_t)来实现生产者和消费者之间的同步。当缓冲区满时,生产者会等待not_full条件变量;当缓冲区空时,消费者会等待not_empty条件变量。每次生产或消费一个数据项后,相应的条件变量会被触发,以通知等待的线程可以继续执行。

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

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

相关文章

Flutter 中的 TabBarView 小部件:全面指南

Flutter 中的 TabBarView 小部件&#xff1a;全面指南 在Flutter中&#xff0c;TabBarView是一个用于创建选项卡式界面的小部件&#xff0c;它与TabController一起使用&#xff0c;可以构建复杂的选项卡导航界面。本文将为您提供一个全面的指南&#xff0c;帮助您了解如何使用…

ssl证书价格一年多少钱?怎么申请?

随着各大平台下架了一年期免费证书&#xff0c;免费证书的有效期都为90天。更多企业选择付费证书。费用是众多用户关心的话题&#xff0c;一年期SSL证书价格在几十到几千元不等。 一年期SSL证书价格查看https://www.joyssl.com/certificate/select/0-1000.html?nid16 下面是…

如何官方查询论文分区,中科院及JCR

中科院分区 有一个小程序&#xff1a;中科院文献情报中心分区表 点2023升级版&#xff0c;输入期刊名 大类1区 JCR分区 进入官方网站 Journal Citation Reports 输入要查询的期刊名&#xff0c;点开 拼命往下拉 这就是根据影响因子的排名&#xff0c;在computer science&am…

农业场景下的slam论文汇总

文章目录 概述2020Ground-Level Mapping and Navigating for Agriculture Based on IoT and Computer VisionCanopy Density Estimation in Perennial Horticulture Crops Using 3D Spinning Lidar SLAM 2021Mobile 3D scan LiDAR: a literature reviewSLAM in the Field: An E…

华为欧拉 openEuler 22.03 LTS SP3 一键安装 Oracle 21C RAC

前言 Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 LTS SP3 一键安装 Oracle 21C RAC 过程&#xff08;全程无需人工干预&#xff09;。 ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 安装准备 1、安装好操作系统&#xff0c;建议安装图形化2、配置好网…

git版本回退

代码推送到远程仓库之后想回退并且不保留任何历史记录&#xff1a; 查看版本号信息git log&#xff1a; git log commit version_example1 (HEAD -> dev, origin/dev, origin/HEAD) Author: xxx <email> Date: xxxXXX注释commit version_example2 Author: xxx <…

【Linux】在内网环境通过代理使用公网Docker镜像

一般来说&#xff0c;软件公司的开发环境多位于内网中&#xff0c;在容器的使用上会使用内部镜像源。但是&#xff0c;内部软件源上的镜像总是不那么丰富&#xff0c;如果想使用公网镜像&#xff0c;该怎么办&#xff1f; 文章目录 1、确定有一台可访问公网的机器2、在该机器上…

Unity 读取本地xml出现的问题

当时遇到的第一个问题是&#xff0c;想要有个读取xml的方法&#xff0c;写在了Ienumerator里面的。所以需要等待文本读写完毕&#xff0c;获得文本的数据&#xff0c;才能执行下一步的代码。 解决办法&#xff1a;在方法执行到最后的时候&#xff0c;增加回调函数。 还有一个…

flutter webview加载本地文件出现跨域解决方案

一直报错 [INFO:CONSOLE(17)] "Access to image at file:///android_asset/flutter_assets/assets/jump/box_bottom.png from origin null has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome…

对话阿里云云原生产品负责人李国强:推进可观测产品与OpenTelemetry开源生态全面融合

5 月 22 日&#xff0c;在最新一期的飞天发布时刻上&#xff0c;阿里云宣布多款可观测产品全面升级&#xff0c;其中一项是应用实时监控服务 ARMS 在业内率先推进了与 OpenTelemetry 开源生态的全面融合&#xff0c;极大丰富了可观测的数据类型及规模&#xff0c;大幅增强了 AR…

带你玩转OpenHarmony AI:打造智能语音子系统

简介 AI时代&#xff0c;智者当先&#xff0c;判断一个终端设备是否智能&#xff0c;语音能力是必不可缺的。智能家居、智慧厨房、智能汽车等等&#xff0c;一切衣食住行都在往智能方向发展&#xff0c;那我们该如何在OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&am…

使用Java Stream API的map方法将包含Long类型ID的流转换为String数组

在这个例子中&#xff0c;idList是一个包含Long类型ID的列表。我们使用stream()方法创建一个流&#xff0c;然后应用map(String::valueOf)方法将Long类型的ID转换为String类型。最后&#xff0c;我们使用toArray(String[]::new)方法将流中的元素收集到一个新的String[]数组中。…

【spark001】SparkSQL内置函数手册总结(更新中)

1.熟悉、梳理、总结下SparkSQL相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 文章目录 1.函数清单 1.函数清…

未来十年,IT行业的无限可能!

未来十年&#xff0c;IT行业的无限可能&#xff01; &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学…

Netty-时间轮

Netty-时间轮 归档 GitHub: Netty-时间轮 参考 Netty-时间轮 说明 其实 Netty 框架并没有使用&#xff0c;其可做学习算法原理的参考 单元测试 public class HashedWheelTimerTest2 {public static void main(String[] args) {System.out.println("---------> &qu…

多联机分户计费控制系统

中央空调多联机分户计费控制系统&#xff0c;针对国内常见几种品牌的多联机空调系统实行&#xff0c;远程控制与计费管理。系统采用MQTT网络协议&#xff0c;以订阅/发布模式实行设备感知&#xff0c;实现对室外机、室内机的状态监测、实时故障报警、累计分摊费用的实时数据传导…

AI - 各类AI针对Excel分析对比

一个水果销量表&#xff0c;Excel包含多个年份sheet&#xff0c;需要提取某个品种的水果每年的销量&#xff0c;看看几个AI的分析结果吧 1、文心一言3.5&#xff08;不支持Excel&#xff09; 不支持上传Excel文件 2、 通义千问2.5&#xff08;完成★&#xff09; 顺利完成…

C++-函数

函数&#xff08;Function&#xff09;&#xff1a;是一个提前封装好的、可重复使用的、完成特定功能的独立代码单元。 特点&#xff1a;提前封装、可重复使用的、完成特定功能 将针对特定功能的、有重复使用需求的代码&#xff0c;提前封装到函数内&#xff0c; 在需要的时候…

Linux(openEuler22.03) 定时备份任务 解决方案

目录 定时备份与清理服务环境需求概述步骤详解1. 配置 rsyncd 服务在 backup 服务器上配置 rsyncd 2. 在 nfs01 和 web01 上配置备份脚本脚本&#xff1a;backup_configs.sh配置定时任务 3. 在 backup 服务器上配置同步和清理脚本脚本&#xff1a;cleanup_backups.sh配置定时任…

游戏陪玩/在线租号/任务系统网站源码

源码介绍 游戏陪玩系统/在线租号系统/小姐姐陪玩任务系统/网游主播任务威客平台源码/绝地吃鸡LOL在线下单/带手机端/声优线上游戏任务系统网站源码 界面美观,功能齐全,已对接支付,安装教程放源码压缩包里了! 界面截图 源码下载 https://download.csdn.net/download/huayula…