DAY6 线程

作业1:

        多线程实现文件拷贝,线程1拷贝一半,线程2拷贝另一半,主线程回收子线程资源。

代码:

#include <myhead.h>
sem_t sem1;
void *copy1()//子线程1函数 拷贝前一半内容
{
	int fd1=open("./1.txt",O_RDONLY);
	int fd2=open("./2.txt",O_CREAT|O_RDWR|O_APPEND,0664);
	if(fd1==-1)
	{
		perror("open");
	}
	if(fd2==-1)
	{
		perror("open");
	}
	char s[100];
	int sum1=0,res1=0;
	int len=lseek(fd1,0,SEEK_END);//统计文件字节数
	lseek(fd1,0,SEEK_SET);//统计完光标要返回
	while(1)
	{
		res1=read(fd1,s,sizeof(s));
		sum1+=res1;//每读一次,把读取长度加起来
		if(res1==0||sum1>len/2)
		{
			int k=res1-(sum1-len/2);//该次读取字节数-超过len/2的字节数
			write(fd2,s,k);
			break;
		}
		write(fd2,s,sizeof(s));//把读取到的字节写入2.txt
	}
	printf("线程1拷贝完成\n");
	close(fd1);
	close(fd2);
	sem_post(&sem1);
	pthread_exit(NULL);
}
void *copy2()//子线程2函数  拷贝后一半内容
{
	sem_wait(&sem1);
	int fd1=open("./1.txt",O_RDONLY);
	int fd2=open("./2.txt",O_CREAT|O_RDWR|O_APPEND,0664);
	if(fd1==-1)
	{
		perror("open");
	}
	if(fd2==-1)
	{
		perror("open");
	}
	int fd3;
	int res2=0;
	int len=lseek(fd1,0,SEEK_END);//统计文件字节数
	lseek(fd1,0,SEEK_SET);//统计完光标要返回
	dup2(fd1,fd3);//fd3重定向fd1
	lseek(fd3,len/2,SEEK_SET);//fd3光标移动中间
	char s[100];
	while(1)
	{
		res2=read(fd3,s,sizeof(s));
		if(res2==0)
		{
			break;
		}
		write(fd2,s,res2);
	}
	printf("线程2拷贝完成\n");
	close(fd1);
	close(fd2);
	close(fd3);
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	pthread_t tid1,tid2;
	sem_init(&sem1,0,0);
	if(pthread_create(&tid1,NULL,copy1,NULL))
	{
		perror("pthread_create");
		return -1;
	}
	if(pthread_create(&tid2,NULL,copy2,NULL))
	{
		perror("pthread_create");
		return -1;
	}
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	printf("回收完成\n");
	sem_destroy(&sem1);
	return 0;
}

运行测试结果:

作业2:线程同步之条件变量

        生产者先让消费者组成一个队列,生产者生产了一台劳斯莱斯,唤醒第一个消费者来消费,然后再生产第二台劳斯莱斯,唤醒第二个消费者来消费,这样可以精确化的控制生产者线程和消费者线程的协同

代码:

#include <myhead.h>
#define MAX 10
pthread_cond_t cond;
pthread_mutex_t mtx;
sem_t sem;
int n=0,count=0;
void *producer()
{
	for(int i=0;i<MAX;i++)
	{
		sem_wait(&sem);//用条件变量卡一下
		n++;
		printf("生产了一台特斯拉%d\n",n);
		pthread_cond_signal(&cond);//唤醒一个等待线程
	}
	pthread_exit(NULL);
}
void *consumer()
{
	pthread_mutex_lock(&mtx);//进入后锁住
	pthread_cond_wait(&cond,&mtx);//条件变量每接受一次进入后重新上锁
	count++;
	printf("消费了一台特斯拉%d\n",count);
	usleep(200000);
	pthread_mutex_unlock(&mtx);
	sem_post(&sem);//条件变量放行
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	pthread_t tid1,tid2[MAX];
	pthread_cond_init(&cond,NULL);//条件变量
	pthread_mutex_init(&mtx,NULL);//互斥锁
	sem_init(&sem,0,1);//条件变量
	if(pthread_create(&tid1,NULL,producer,NULL)!=0)
	{
		perror("pthread_create");
		return -1;
	}
	for(int i=0;i<MAX;i++)
	{
		if(pthread_create(&tid2[i],NULL,consumer,NULL)!=0)
		{
			perror("pthread_create");
			return -1; 
		}
	}
	pthread_join(tid1,NULL);
	for(int i=0;i<MAX;i++)
	{
		pthread_join(tid2[i],NULL);
	}
	pthread_mutex_destroy(&mtx);
	pthread_cond_destroy(&cond);
	return 0;
}

运行测试结果:

作业3:

互斥锁,无名信号量,条件变量再练习一遍

1.互斥锁代码如何实现

代码:

#include <myhead.h>
pthread_mutex_t mtx;//定义互斥锁
void *fun(void *n)
{
	pthread_mutex_lock(&mtx);//上锁
	printf("%d\n",*(int *)n);
	pthread_mutex_unlock(&mtx);//解锁
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	pthread_t tid1,tid2;
	int num1=1,num2=2;
	pthread_mutex_init(&mtx,NULL);//初始化互斥锁
	if(pthread_create(&tid1,NULL,fun,&num1))//子线程1
	{
		perror("pthread_create");
		return -1;
	}
	if(pthread_create(&tid2,NULL,fun,&num2))//子线程2
	{
		perror("pthread_create");
		return -1;
	}
	pthread_join(tid1,NULL);//阻塞回收线程
	pthread_join(tid2,NULL);
	pthread_mutex_destroy(&mtx);//毁锁
	return 0;
}

运行测试结果:

2.无名信号量

代码:

#include <myhead.h>
#define MAX 5
sem_t sem;//定义无名信号量
int n=0;
void *producer()
{
	for(int i=0;i<MAX;i++)
	{
	   n++;
       printf("生产了特斯拉%d\n",n);
	}
	sem_post(&sem);//释放无名变量
	pthread_exit(NULL);
}
void *consumer()
{
    sem_wait(&sem);//申请无名变量
	printf("消费了一台特斯拉%d\n",n);
	n--;
	sem_post(&sem);
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	pthread_t tid1,tid[MAX];
	sem_init(&sem,0,0);//初始化无名信号量
	if(pthread_create(&tid1,NULL,producer,&n)!=0)
	{
		perror("pthread_create");
		return -1;
	}
	for(int i=0;i<MAX;i++)
	{
		if(pthread_create(&tid[i],NULL,consumer,&n)!=0)
		{
			perror("pthread_create");
			return -1;
		}
	}
	pthread_join(tid1,NULL);
	for(int i=0;i<MAX;i++)
	{
		pthread_join(tid[i],NULL);
	}
	sem_destroy(&sem);//销毁无名变量
	return 0;
}

运行测试结果:

3.条件变量

见作业2

Xmind知识点:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Window.history API学习笔记

Window.history API学习笔记 在现代前端开发中&#xff0c;单页应用&#xff08;SPA&#xff09;的流行让我们对于页面的浏览历史管理需求愈加明显。window.history API作为浏览器提供的原生API&#xff0c;能够帮助开发者更加细致地控制用户的导航体验。本文将介绍window.his…

Hbase集群搭建

1. 环境 三台节点hadoop 集群zookeeper 集群hbase 1.1环境准备 使用前文hdfs三台节点 1.11 zookeeper搭建 下载 wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz解压 tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz zookee…

物联网(RFID)全景:被装信息化监控应用与挑战

一、被装物联网信息化建设的动因 信息化改革在20世纪80年代中期启航&#xff0c;旨在提升被装保障的效率。随着时间的推移&#xff0c;硬件的广泛运用和软件的快速迭代&#xff0c;装备业务在规划、制造、分发以及战时支援等核心环节&#xff0c;已经与信息系统深度融合&#x…

2024 年 10 月公链行业研报:比特币引领市场,Layer 2 竞争加剧

作者&#xff1a;Stella L (stellafootprint.network) 数据来源&#xff1a;Footprint Analytics 公链研究页面 在中本聪于 2008 年 10 月 31 日发布比特币白皮书整整 16 年后&#xff0c;比特币再次展现了其对金融世界的革命性影响。2024 年 10 月&#xff0c;在机构投资者…

NCC前端调用查询弹框

系统自带的查询模板 弹框 调启使用默认的 查询模板 是在 单据模板的 列表模板中&#xff0c;有个查询区域 &#xff0c;查询区域就是查询模板内容如果在列表页做客开 新增按钮 调启查询模板 无问题&#xff0c;但是目前需求是需要再卡片页面下调启系统标准的调启模板代码 //调…

网络安全常见面试题--含答案

本文面试题汇总&#xff1a; 防范常见的 Web 攻击 重要协议分布层 arp协议的工作原理rip协议是什么&#xff1f;rip的工作原理 什么是RARP&#xff1f;工作原理OSPF协议&#xff1f;OSPF的工作原理 TCP与UDP区别总结 什么是三次握手四次挥手&#xff1f; tcp为什么要三次握手&…

Vue 3 在现代前端开发中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Vue 3 在现代前端开发中的应用 Vue 3 在现代前端开发中的应用 Vue 3 在现代前端开发中的应用 引言 Vue 3 概述 定义与原理 发展历…

Python 正则表达式使用指南

Python 正则表达式使用指南 正则表达式&#xff08;Regular Expression, 简称 regex&#xff09;是处理字符串和文本的强大工具。它使用特定的语法定义一组规则&#xff0c;通过这些规则可以对文本进行匹配、查找、替换等操作。Python 提供了 re 模块&#xff0c;使得正则表达…

OpenGL Phong光照模型-镜面反射-反射方向推导

反射方向计算公式如下&#xff1a; 其中R表示反射方向&#xff0c;L表示入射方向&#xff0c;N表示法向&#xff08;单位向量&#xff09;。 该公式推导如下&#xff1a; 1、首先入射方向、反射方向向量可分成两个分量分别是&#xff1a; 与法向N平行分量Ln、垂直于法向N分量…

006配置DHCP服务器

DHCP可以自动为计算机分配IP地址 环境准备 准备两台Linux系统和一台windows系统DHCP 服务器的IP地址为&#xff1a;192.168.239.100192.168.239.0/24 网络中有两个IP地址空间可以分配&#xff0c;因为100作为dhcp服务器地址 分别是&#xff1a; 192.168.239.1 ~ 192.168.239.…

基于微信小程序的药店管理系统+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、普通用户功能模块&#xff1a;管理员&#xff08;用户管理、药品分类管理、药品信息管理、系统管理、订单管理等&#xff09;&#xff0c;普通用户&#xff08;查看相关药品信息、充值、登录注册、个人中心、购物车、我的订单等&#…

https网站 请求http图片报错:net::ERR_SSL_PROTOCOL_ERROR

问题描述 场景&#xff1a; https网站&#xff0c;请求http图片资源报错&#xff1a;net::ERR_SSL_PROTOCOL_ERROR 原因&#xff1a; Chrome 81 中&#xff0c;对混合内容资源加载策略进行了改变&#xff0c;会自动升级到 https:// &#xff0c;如果无法通过 https:// 加载&am…

JAVA后端生成图片滑块验证码 springboot+js完整案例

前言 现在大部分网部都是图片滑块验证码&#xff0c;这个得要与后端联动起来才是确保接口安全性 通过我们系统在发送手机短息时都会选进行滑块验证&#xff0c;但是我们要保证发送短息接口的全安&#xff0c;具体路思如下 那么这个滑块的必须是与后端交互才能保证安全性&…

Golang | Leetcode Golang题解之第556题下一个更大元素III

题目&#xff1a; 题解&#xff1a; func nextGreaterElement(n int) int {x, cnt : n, 1for ; x > 10 && x/10%10 > x%10; x / 10 {cnt}x / 10if x 0 {return -1}targetDigit : x % 10x2, cnt2 : n, 0for ; x2%10 < targetDigit; x2 / 10 {cnt2}x x2%10 -…

ceph介绍和搭建

1 为什么要使用ceph存储 什么是对象存储&#xff1f; 对象存储并没有向文件系统那样划分为元数据区域和数据区域&#xff0c;而是按照不同的对象进行存储&#xff0c;而且每个对象内部维护着元数据和数据区域。因此每个对象都有自己独立的管理格式。 对象存储优点&#xff1a…

MFC图形函数学习07——画扇形函数

绘制扇形函数是MFC中绘图的基本函数&#xff0c;它绘制的仍是由椭圆弧与椭圆中心连线构成的椭圆扇形&#xff0c;特例是由圆弧与圆心连线构成的圆扇形。 一、绘制扇形函数 原型&#xff1a;BOOL Pie(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); …

macOS15.1及以上系统bug:开发者证书无法打开,钥匙串访问无法打开一直出现图标后立马闪退

团队紧跟苹果最新系统发现bug:今日设备信息如下,希望能带给遇到这个问题的开发者一点帮助。 错误图如下: 点击证书文件后,先出现钥匙串访问图标,后立马闪退消失 中间试过很多方法,都是一样的表现,最后好在解决了,看网上也没有相关的帖子,这里直接写解决办法和导致原因…

Kotlin约束泛型参数必须继承自某个父类

Kotlin约束泛型参数必须继承自某个父类 open class SuperData { }class DataA : SuperData {constructor() {println("DataA constructor")} }class DataB : SuperData {constructor() {println("DataB constructor")} }fun <T : SuperData> myfun(p…

量子计算及其在密码学中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 量子计算及其在密码学中的应用 量子计算及其在密码学中的应用 量子计算及其在密码学中的应用 引言 量子计算概述 定义与原理 发展…

【大数据学习 | HBASE高级】storeFile文件的合并

Compaction 操作分成下面两种&#xff1a; Minor Compaction&#xff1a;是选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile&#xff0c;对于删除、过期、多余版本的数据不进行清除。 Major Compaction&#xff1a;是指将所有的StoreFile合并成一个StoreFile&am…