IO学习---->线程

1.创建两个线程,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分

#include <head.h>
sem_t sem;
long half_size = 0;  // 全局变量,供所有线程共享void* product(void *arg) 
{FILE *src = fopen("IO.text", "rb");FILE *dest = fopen("IO1.text", "rb+");if (src == NULL || dest == NULL) {perror("文件打开失败");pthread_exit(NULL);}char buf[128] = {0};size_t n;while ((n = fread(buf, 1, sizeof(buf), src)) > 0) {if (ftell(src) > half_size) {n -= (ftell(src) - half_size); // 防止越界写入}if (fwrite(buf, 1, n, dest) != n) {perror("线程1写入失败");fclose(src);fclose(dest);pthread_exit(NULL);}if (ftell(src) >= half_size) {break;  // 退出循环,完成前半部分写入}}printf("线程1完成文件前半部分的拷贝。\n");fclose(src);fclose(dest);sem_post(&sem);  // 通知消费者线程pthread_exit(NULL);
}void* consumer(void *arg) 
{sem_wait(&sem);  // 等待生产者完成前半部分FILE *src_child = fopen("IO.text", "rb");FILE *dest_child = fopen("IO1.text", "rb+");if (src_child == NULL || dest_child == NULL) {perror("文件打开失败");pthread_exit(NULL);}fseek(src_child, half_size, SEEK_SET);fseek(dest_child, half_size, SEEK_SET);char buf[128] = {0};size_t n;while ((n = fread(buf, 1, sizeof(buf), src_child)) > 0) {if (fwrite(buf, 1, n, dest_child) != n) {perror("线程2写入失败");fclose(src_child);fclose(dest_child);pthread_exit(NULL);}}printf("线程2完成文件后半部分的拷贝。\n");fclose(src_child);fclose(dest_child);pthread_exit(NULL);
}int main(int argc, const char *argv[]) 
{FILE *src = fopen("IO.text", "rb");if (src == NULL) {perror("打开源文件失败");return -1;}FILE *dest = fopen("IO1.text", "wb");if (dest == NULL) {perror("打开目标文件失败");fclose(src);return -1;}// 计算文件大小和一半位置fseek(src, 0, SEEK_END);long file_size = ftell(src);rewind(src);half_size = file_size / 2;sem_init(&sem, 0, 0);pthread_t tid1, tid2;if ((errno = pthread_create(&tid1, NULL, product, NULL)) != 0) {perror("pthread_create error");}if ((errno = pthread_create(&tid2, NULL, consumer, NULL)) != 0) {perror("pthread_create error");}pthread_join(tid1, NULL);pthread_join(tid2, NULL);sem_destroy(&sem);fclose(src);fclose(dest);return 0;
}

2.创建3个线程,线程A打印A,线程B打印B,线程C打印C,要求重复打印顺序ABC  (分别使用信号量和条件变量实现)

#include <head.h>
//创建信号量
sem_t sema;
sem_t semb;
sem_t semc;
void* pta(void* arg)
{while(1){//sleep(1);sem_wait(&sema);printf("A\n");sem_post(&semb);}pthread_exit(NULL);
}void* ptb(void* arg)
{while(1){//sleep(1);sem_wait(&semb);printf("B\n");sem_post(&semc);}pthread_exit(NULL);
}void* ptc(void* arg)
{while(1){sleep(1);sem_wait(&semc);printf("C\n");sem_post(&sema);}pthread_exit(NULL);
}int main(int argc, const char *argv[])
{sem_init(&sema,0,1);sem_init(&semb,0,0);sem_init(&semc,0,0);pthread_t std1,std2,std3;if((errno=pthread_create(&std1,NULL,pta,NULL))!=0)PRINT_ERROR("pthread_create error");if((errno=pthread_create(&std2,NULL,ptb,NULL))!=0)PRINT_ERROR("pthread_create error");if((errno=pthread_create(&std3,NULL,ptc,NULL))!=0)PRINT_ERROR("pthread_create error");pthread_join(std1,NULL);pthread_join(std2,NULL);pthread_join(std3,NULL);sem_destroy(&sema);sem_destroy(&semb);sem_destroy(&semc);return 0;
}
#include <head.h>
//定义并初始化条件变量
pthread_cond_t cond3 =PTHREAD_COND_INITIALIZER;
pthread_cond_t cond1 =PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 =PTHREAD_COND_INITIALIZER;
//定义并初始化互斥锁
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//设置标志位取消sleepint flag =0;
//pthread_cond_t cond;
//pthread_cond_init(&cond,NULL);
void* pta(void *arg)
{while(1){//  sleep(1);//放弃CPU资源,使cpu一定先使用消费者线程pthread_mutex_lock(&mutex);if(flag!=0)pthread_cond_wait(&cond3,&mutex);printf("A\n");flag=1;pthread_cond_signal(&cond1);pthread_mutex_unlock(&mutex);}pthread_exit(NULL);
}
void* ptb(void *arg)
{while(1){//上锁pthread_mutex_lock(&mutex);if(flag!=1)//阻塞休眠并解锁pthread_cond_wait(&cond1,&mutex);printf("B\n");flag=2;//解锁pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond2);}pthread_exit(NULL);
}
void* ptc(void *arg)
{while(1){//上锁pthread_mutex_lock(&mutex);if(flag!=2)//阻塞休眠并解锁pthread_cond_wait(&cond2,&mutex);printf("C\n");flag=0;//解锁pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond3);}pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{pthread_t std1,std2,std3,std4,std5;if( (errno=pthread_create(&std1,NULL,pta,NULL))!=0){PRINT_ERROR("pthread_create error");}if((errno=pthread_create(&std2,NULL,ptb,NULL))!=0){                                                                              PRINT_ERROR("pthread_create error");}if((errno=pthread_create(&std3,NULL,ptc,NULL))!=0){PRINT_ERROR("pthread_create error");}pthread_join(std1,NULL);pthread_join(std2,NULL);pthread_join(std3,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond3);pthread_cond_destroy(&cond1);pthread_cond_destroy(&cond2);return 0;
}

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

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

相关文章

深度学习分词器char-level实战详解

一、三种分词器基本介绍 word-level&#xff1a;将文本按照空格或者标点分割成单词&#xff0c;但是词典大小太大 subword-level&#xff1a;词根分词&#xff08;主流&#xff09; char-level&#xff1a;将文本按照字母级别分割成token 二、charlevel代码 导包&#xff1…

基于SpringBoot实现旅游酒店平台功能六

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高&#xff0c;旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求&#xff0c;旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上&#xff0…

git规范提交之commitizen conventional-changelog-cli 安装

一、引言 使用规范的提交信息可以让项目更加模块化、易于维护和理解&#xff0c;同时也便于自动化工具&#xff08;如发布工具或 Changelog 生成器&#xff09;解析和处理提交记录。 通过编写符合规范的提交消息&#xff0c;可以让团队和协作者更好地理解项目的变更历史和版本…

前端实现版本更新自动检测✅

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位资深前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&a…

硬件基础(4):(5)设置ADC电压采集中MCU的参考电压

Vref 引脚通常是 MCU (特别是带有 ADC 的微控制器) 上用来提供或接收基准电压的引脚&#xff0c;ADC 会以该基准电压作为量程参考对输入模拟信号进行数字化转换。具体来说&#xff1a; 命名方式 在不同厂家的 MCU 中&#xff0c;Vref 引脚可能会被标记为 VREF / VREF- / VREF_…

postman接口请求中的 Raw是什么

前言 在现代的网络开发中&#xff0c;API 的使用已经成为数据交换的核心方式之一。然而&#xff0c;在与 API 打交道时&#xff0c;关于如何发送请求体&#xff08;body&#xff09;内容类型的问题常常困扰着开发者们&#xff0c;尤其是“raw”和“json”这两个术语之间的区别…

为什么要使用前缀索引,以及建立前缀索引:sql示例

背景&#xff1a; 你想啊&#xff0c;数据库里有些字段&#xff0c;它老长了&#xff0c;就像那种 varchar(255) 的字段&#xff0c;这玩意儿要是整个字段都拿来建索引&#xff0c;那可太占地方了。打个比方&#xff0c;这就好比你要在一个超级大的笔记本上记东西&#xff0c;每…

【语料数据爬虫】Python爬虫|批量采集会议纪要数据(1)

前言 本文是该专栏的第2篇,后面会持续分享Python爬虫采集各种语料数据的的干货知识,值得关注。 在本文中,笔者将主要来介绍基于Python,来实现批量采集“会议纪要”数据。同时,本文也是采集“会议纪要”数据系列的第1篇。 采集相关数据的具体细节部分以及详细思路逻辑,笔…

Android 线程池实战指南:高效管理多线程任务

在 Android 开发中&#xff0c;线程池的使用非常重要&#xff0c;尤其是在需要处理大量异步任务时。线程池可以有效地管理线程资源&#xff0c;避免频繁创建和销毁线程带来的性能开销。以下是线程池的使用方法和最佳实践。 1. 线程池的基本使用 &#xff08;1&#xff09;创建线…

SQL29 计算用户的平均次日留存率

SQL29 计算用户的平均次日留存率 计算用户的平均次日留存率_牛客题霸_牛客网 题目&#xff1a;现在运营想要查看用户在某天刷题后第二天还会再来刷题的留存率。 示例&#xff1a;question_practice_detail -- 输入&#xff1a; DROP TABLE IF EXISTS question_practice_detai…

深度学习分类回归(衣帽数据集)

一、步骤 1 加载数据集fashion_minst 2 搭建class NeuralNetwork模型 3 设置损失函数&#xff0c;优化器 4 编写评估函数 5 编写训练函数 6 开始训练 7 绘制损失&#xff0c;准确率曲线 二、代码 导包&#xff0c;打印版本号&#xff1a; import matplotlib as mpl im…

【leetcode hot 100 19】删除链表的第N个节点

解法一&#xff1a;将ListNode放入ArrayList中&#xff0c;要删除的元素为num list.size()-n。如果num 0则将头节点删除&#xff1b;否则利用num-1个元素的next删除第num个元素。 /*** Definition for singly-linked list.* public class ListNode {* int val;* Lis…

【iOS逆向与安全】sms短信转发插件与上传服务器开发

一、目标 一步步分析并编写一个短信自动转发的deb插件 二、工具 mac系统已越狱iOS设备:脱壳及frida调试IDA Pro:静态分析测试设备:iphone6s-ios14.1.1三、步骤 1、守护进程 ​ 守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。例如:推送服务、人…

Midjourney绘图参数详解:从基础到高级的全面指南

引言 Midjourney作为当前最受欢迎的AI绘图工具之一&#xff0c;其强大的参数系统为用户提供了丰富的创作可能性。本文将深入解析Midjourney的各项参数&#xff0c;帮助开发者更好地掌握这一工具&#xff0c;提升创作效率和质量。 一、基本参数配置 1. 图像比例调整 使用--ar…

音频进阶学习十九——逆系统(简单进行回声消除)

文章目录 前言一、可逆系统1.定义2.解卷积3.逆系统恢复原始信号过程4.逆系统与原系统的零极点关系 二、使用逆系统去除回声获取原信号的频谱原系统和逆系统幅频响应和相频响应使用逆系统恢复原始信号整体代码如下 总结 前言 在上一篇音频进阶学习十八——幅频响应相同系统、全…

vue3 使用sass变量

1. 在<style>中使用scss定义的变量和css变量 1. 在/style/variables.scss文件中定义scss变量 // scss变量 $menuText: #bfcbd9; $menuActiveText: #409eff; $menuBg: #304156; // css变量 :root {--el-menu-active-color: $menuActiveText; // 活动菜单项的文本颜色--el…

gbase8s rss集群通信流程

什么是rss RSS是一种将数据从主服务器复制到备服务器的方法 实例级别的复制 (所有启用日志记录功能的数据库) 基于逻辑日志的复制技术&#xff0c;需要传输大量的逻辑日志,数据库需启用日志模式 通过网络持续将数据复制到备节点 如果主服务器发生故障&#xff0c;那么备用服务…

熵与交叉熵详解

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 ima 知识库 知识库广场搜索&#…

程序化广告行业(3/89):深度剖析行业知识与数据处理实践

程序化广告行业&#xff08;3/89&#xff09;&#xff1a;深度剖析行业知识与数据处理实践 大家好&#xff01;一直以来&#xff0c;我都希望能和各位技术爱好者一起在学习的道路上共同进步&#xff0c;分享知识、交流经验。今天&#xff0c;咱们聚焦在程序化广告这个充满挑战…

探索在生成扩散模型中基于RAG增强生成的实现与未来

概述 像 Stable Diffusion、Flux 这样的生成扩散模型&#xff0c;以及 Hunyuan 等视频模型&#xff0c;都依赖于在单一、资源密集型的训练过程中通过固定数据集获取的知识。任何在训练之后引入的概念——被称为 知识截止——除非通过 微调 或外部适应技术&#xff08;如 低秩适…