当前位置: 首页 > news >正文

利用互斥锁实现多个线程写一个文件

代码

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>FILE *fp;//线程函数1
void *wrfunc1(void *arg);
//线程函数2
void *wrfunc2(void *arg);
//线程函数3
void *wrfunc3(void *arg);//静态创建互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int main(int argc, char *argv[])
{//三个线程idpthread_t tid1;pthread_t tid2;pthread_t tid3;//三个线程参数int arg1 = 1;int arg2 = 2;int arg3 = 3;//三个线程返回值void *ret1;void *ret2;void *ret3;if ((fp = fopen("test.txt", "a+")) == NULL){perror("fopen");}//创建三个线程pthread_create(&tid1, NULL, wrfunc1, &arg1);sleep(2);pthread_create(&tid2, NULL, wrfunc2, &arg2);sleep(2);pthread_create(&tid3, NULL, wrfunc3, &arg3);sleep(2);//延长休眠时间,保证三个线程都有机会执行sleep(100);//取消线程pthread_cancel(tid1);pthread_cancel(tid2);pthread_cancel(tid3);//回收线程pthread_join(tid1, &ret1);pthread_join(tid2, &ret2);pthread_join(tid3, &ret3);return 0;
}void *wrfunc1(void *arg)
{	char str[] = "I am thread1, I write a line\n"; //线程要写入文件的字符串int i;printf("this is thread%d\n", *(int*)arg);while (1){pthread_mutex_lock(&mutex); //加入互斥锁//按字符将字符串循环写入文件for (i = 0; i < strlen(str); i++){fputc(str[i], fp);usleep(1);}pthread_mutex_unlock(&mutex); //释放互斥锁pthread_testcancel(); //设置线程取消点}sleep(10);pthread_exit("thread1 return"); //退出线程
}void *wrfunc2(void *arg)
{char str[] = "I am thread2, I write a line\n";int i;printf("this is thread%d\n", *(int*)arg);while (1){pthread_mutex_lock(&mutex);for (i = 0; i < strlen(str); i++){fputc(str[i], fp);usleep(1);}pthread_mutex_unlock(&mutex);pthread_testcancel();}sleep(10);pthread_exit("thread2 return");
}void *wrfunc3(void *arg)
{char str[] = "I am thread3, I write a line\n";int i;printf("this is thread%d\n", *(int*)arg);while (1){pthread_mutex_lock(&mutex);for (i = 0; i < strlen(str); i++){fputc(str[i], fp);usleep(1);}pthread_mutex_unlock(&mutex);pthread_testcancel();}sleep(10);pthread_exit("thread3 return");
}

总结

  • 在这个代码中,是需要加入 pthread_cancel() 函数的因为:线程函数wrfunc1、wrfunc2和wrfunc3都包含一个无限循环,循环内部没有明确的退出条件。没有明确的退出条件意味着线程函数会一直执行下去,直到程序结束或者发生了某个特殊的情况导致线程被强制终止。在这种情况下,如果没有使用pthread_cancel,线程将一直运行下去,不会自动退出。
  • 这个代码中的 sleep(100) 是必须加入的,如果不加入那么 线程 2 和 线程 3 将没有机会执行,也就看不到正确的结果。

相关文章:

利用互斥锁实现多个线程写一个文件

代码 #include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h>FILE *fp;//线程函数1 void *wrfunc1(void *arg); //线程函数2 void *wrfunc2(void *arg); //线程函数3 void *wrfunc3(void *arg);//静态创建互斥锁 pthread_…...

【m98】视频缓存PacketBuffer 1 : SeqNumUnwrapper int64映射、ForwardDiff

视频缓存PacketBuffer 对rtp包进行接收处理。 rtp序号 相关 【mediasoup】RtpStreamRecv 对rtp 序号的验证 与这里的处理有不同。...

day58:ARMday5,GPIO流水灯实验

汇编指令&#xff1a; .text .global _start _start: 1.设置GPIOE GPIOF寄存器的时钟使能 RCC_MP_AHB4ENSETR[5:4]->1 0x50000a28 LDR R0,0x50000a28 LDR R1,[R0] ORR R1,R1,#(0x3<<4) STR R1,[R0]2.设置PE10、PF10、PE8管脚为输出模式&#xff0c;GPIOE_MODER[21…...

Linux shell编程学习笔记9:字符串运算 和 if语句

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算&#xff0c;同样也需要进行根据条件进行流程控制&#xff0c;提供了if、for、while、until等语句。 上期学习笔记中我们研究了字符串数据的使用&#xff0c;今天我们研…...

【分享】xpath的属性表达式

在XPath中&#xff0c;要选择HTML文档中具有特定类的元素&#xff0c;您通常需要使用属性选择器 [attribute-nameattribute-value] 来选择元素&#xff0c;其中 attribute-name 是属性名称&#xff0c;attribute-value 是要匹配的属性值。对于HTML元素的类选择器&#xff0c;您…...

Oracle Dataguard跨版本数据迁移(11.2.0.4~19.13.0.0)

一、前期准备 按照DG部署步骤修改DG参数、添加standby redo log、配置静态监听、配置tnsnames文件、备端修改参数文件、创建所需目录等配置好部署环境&#xff0c;这里不再赘述&#xff0c;跟正常部署DG无区别。 环境配置好后&#xff0c;进行后面的操作。 二、使用RMAN备份复…...

零基础Linux_14(基础IO_文件)缓冲区+文件系统inode等

目录 1. 缓冲区 1.1 缓冲区的存在 1.2 缓冲区的刷新策略 1.3 模拟C标准库中的文件操作 完整代码及验证&#xff1a; 1.4 重看缓冲区 1.5 stdout和stderr的区别 2. 文件系统 2.1 磁盘的物理结构CHS等 2.2 磁盘的抽象结构LBA等 2.3 文件管理inode等 2.4 对文件的操作…...

Vue中的router路由的介绍(快速入门)

路由的介绍 文章目录 路由的介绍1、VueRouter的介绍2、VueRouter的使用&#xff08;52&#xff09;2.1、5个基础步骤(固定)2.2、两个核心步骤 3、组件存放的目录&#xff08;组件分类&#xff09; 生活中的路由&#xff1a;设备和ip的映射关系&#xff08;路由器&#xff09; V…...

ESP-07S进行TCP 通信测试

一&#xff0c;TCP Server 为 AP 模式&#xff0c;TCP Client 为 Station 模式。 这里电脑pc作为TCP Server&#xff0c;ESP-07S作为TCP Client 。 二&#xff0c;电脑端配置。 1&#xff0c;开启热点。 2&#xff0c;转到“设置”&#xff0c;编辑热点信息。 3&#xff0c;关闭…...

如何找到新媒体矩阵中存在的问题?

随着数字媒体的发展&#xff0c;企业的新媒体矩阵已成为品牌推广和营销的重要手段之一。 然而&#xff0c;很多企业在搭建新媒体矩阵的过程中&#xff0c;往往会忽略一些问题&#xff0c;导致矩阵发展存在潜在风险&#xff0c;影响整个矩阵运营效果。 因此&#xff0c;找到目前…...

MongoDB-基本常用命令

基本常用命令 MongoDB常用命令a) 案例需求b) 数据库操作b.1) 选择和创建数据库b.2) 删除数据库 c) 集合操作c.1) 集合的显示创建c.2) 集合的隐式创建c.3) 集合的删除 d) 文档基本CRUDd.1) 文档的插入(1) 单个文档的插入(2) 批量插入 d.2) 文档的基本查询(1) 查询所有(2) 投影查…...

Linux 常用systemctl service 脚本

文章目录 1. jar 包部署 service 脚本2. nginx 服务安装 脚本3.artemis 服务安装脚本 1. jar 包部署 service 脚本 默认jdk 执行&#xff1a; [Service] Typesimple Userroot WorkingDirectory/opt/app/webserver ExecStart/usr/bin/java -Xms512m -Xss256k -jar /opt/app/we…...

flask-sqlalchemy实现读写分离完整版

1. 依赖版本: alembic==1.6.5 click==8.0.1 colorama==0.4.4 Flask==1.1.2 Flask-Migrate==2.7.0 Flask-Script==2.0.6 Flask-SQLAlchemy==2.4.4 greenlet==1.1.0 itsdangerous==2.0.1 Jinja2==3.0.1 Mako==1.1.4 MarkupSafe==2.0.1 protobuf==3.17.3 PyMySQL==1.0.2 python-…...

windows下在cmd和git bash中执行bash download.sh失败

cmd报错信息&#xff1a; 解决办法&#xff1a; win64-wget-1.21.4 安装软件wget&#xff0c;如下这是64位的包&#xff0c;解压后&#xff0c;下面有个wget.exe&#xff0c;拷贝到C:\Windows\System32、 然后打开cmd&#xff0c;执行wget -V 如上&#xff0c;有版本信息就O…...

rust流程控制

一、分支 &#xff08;一&#xff09;if 1.if 语法格式 if boolean_expression { }例子 fn main(){let num:i32 5;if num > 0 {println!("正数");} }条件表达式不需要用小括号。 条件表达式必须是bool类型。 2.if else 语法格式 if boolean_expression { } …...

虚拟机软件Parallels Desktop 19 mac功能介绍

Parallels Desktop 19 mac是一款虚拟机软件&#xff0c;它允许用户在Mac电脑上同时运行Windows、Linux和其他操作系统。Parallels Desktop提供了直观易用的界面&#xff0c;使用户可以轻松创建、配置和管理虚拟机。 PD19虚拟机软件具有快速启动和关闭虚拟机的能力&#xff0c;让…...

在工业机器视觉领域中应用钡铼技术有限公司的EtherCAT网关

钡铼技术有限公司作为一家专注于业物联网关、工业智能网关、边缘计算网关、ARM嵌入式工业计算机、PLC远程采集网关、Modbus转MQTT网关、OPC UA网关、BACnet网关路由器、Lora网关、工业4G边缘路由器、4G无线远程数据采集模块、4G DTU RTU、以太网远程IO模块、工业总线分布式I/O模…...

ssh指定的密钥协商方式以及Ansible的hosts文件修改密钥协商方式

一、首先你要知道用什么加密协商。 [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details 10.10.2.190 | UNREACHABLE! > {"changed": false,"msg": "Failed to connect to the host via ssh: U…...

NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器

自然语言处理是机器学习和人工智能的一个迷人领域。这篇博客文章启动了一个具体的 NLP 项目&#xff0c;涉及使用维基百科文章进行聚类、分类和知识提取。灵感和一般方法源自《Applied Text Analysis with Python》一书。 一、说明 该文是系列文章&#xff0c;揭示如何对爬取文…...

QT sqlite的简单用法

1、相关头文件 #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> #include <QSqlRecord> #include <QSqlIndex> #include <QSqlField> #include <QFile> #include <QDebug> 2、数据库对象 QSqlDatabas…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...