IO进程线程作业day5

1> 将互斥机制的代码实现重新敲一遍

#include <myhead.h>	
int num=520;//定义一个全局变量
pthread_mutex_t mutex;//创建锁
//线程1任务
void *task1(void *arg)
{
	puts("任务1");
	pthread_mutex_lock(&mutex);//上锁
	num=1314;
	sleep(1);
	printf("task1num=%d\n",num);
	pthread_mutex_unlock(&mutex);//解锁
}
//线程2任务
void *task2(void *arg)
{
	puts("任务2");
	pthread_mutex_lock(&mutex);//上锁
	num++;
	sleep(1);
	printf("task2num=%d\n",num);
	pthread_mutex_unlock(&mutex);//解锁
}

int main(int argc, const char *argv[])
{
	//初始化锁
	pthread_mutex_init(&mutex, NULL);
	//创建两个线程tdi1,tdi2
	pthread_t tid1,tid2;
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("tid1 create error\n");
		return 0;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("tid2 create error\n");
		return 0;
	}
	//以阻塞的形式回收线程资源
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	//销锁
	pthread_mutex_destroy(&mutex);
	return 0;
}

 2> 将无名信号量的代码实现重新敲一遍

#include <myhead.h>	

sem_t sem;//创建无名变量
//线程任务1生产特斯拉
void *task1(void *arg)
{
	int num=3;
	while(num--)
	{
		sleep(1);
		puts("生产特斯拉");
		sem_post(&sem);//value值从0变为1

	}
	pthread_exit(NULL);//退出线程
}
//线程2购买特斯拉
void *task2(void *arg)
{	
	int num=3;
	while(num--)
	{
		sem_wait(&sem);//value值从1变为0;
		puts("购买特斯拉");
	}
	pthread_exit(NULL);//退出线程

}

int main(int argc, const char *argv[])
{
	sem_init(&sem,0,0);//初始化无名变量并让value值变为0
	pthread_t tid1,tid2;//创建一个生产者线程,一个消费者线程
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("tid1 create error\n");
		return 0;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("tid2 create error\n");
		return 0;
	}
	//回收线程资源
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	//销毁无名变量
	sem_destroy(&sem);
	return 0;
}

 3> 将条件变量的代码实现重新敲一遍

#include<myhead.h>
//创建条件变量
pthread_cond_t cond;
//创建互斥锁
pthread_mutex_t mutex;
//生产者线程
void *task1(void *arg)
{
	int num = 5;
	while(num --)
	{
		sleep(1);
		printf("生产了一辆特斯拉\n");
		//唤醒一个消费者
		pthread_cond_signal(&cond);
	}
	pthread_exit(NULL);        //退出线程
}

//消费者线程
void *task2(void *arg)
{  
	pthread_mutex_lock(&mutex);//上锁
	pthread_cond_wait(&cond, &mutex);//等待唤醒
	printf("%#lx:消费了一辆特斯拉\n", pthread_self());
	pthread_mutex_unlock(&mutex);//解锁
	pthread_exit(NULL);
}

int main(int argc, const char *argv[])
{

    
    pthread_cond_init(&cond, NULL); 
    pthread_mutex_init(&mutex, NULL);
    //创建4个线程,分别是一个生产者和三个消费者
    pthread_t tid1, tid2, tid3,tid4;
    if(pthread_create(&tid1, NULL, task1, NULL) != 0)
    {
        printf("tid1 create error\n");
        return 0;
    }

    if(pthread_create(&tid2, NULL, task2, NULL) != 0)
    {
        printf("tid2 create error\n");
        return 0;
    }
    if(pthread_create(&tid3, NULL, task2, NULL) != 0)
    {
        printf("tid3 create error\n");
        return 0;
    }
    if(pthread_create(&tid4, NULL, task2, NULL) != 0)
    {
        printf("tid4 create error\n");
        return 0;
    }
 
    //回收线程资源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);
    pthread_join(tid4, NULL);
    pthread_cond_destroy(&cond);//销毁条件变量
    pthread_mutex_destroy(&mutex);//销毁锁

    return 0;
}

 4> 将无名管道的代码实现重新敲一遍

#include <myhead.h>	

int main(int argc, const char *argv[])
{
	int pipefd[2]={0};//获取管道文件的读端和写端
	if(pipe(pipefd)==-1)
	{
		perror("pipe error");
		return -1;
	}

	pid_t pid =fork();//创建一个进程
	if(pid>0)//父进程
	{
		close(pipefd[0]);//关闭管道文件的读端
		char wbuf[100]="";
		while(1)
		{
			bzero(wbuf,sizeof(wbuf));//清空容器
			fgets(wbuf,sizeof(wbuf),stdin);//从终端获取内容
			wbuf[strlen(wbuf)-1]=0;
			write(pipefd[1],wbuf,strlen(wbuf));//把容器内容写进管道文件
			if(strcmp(wbuf,"end")==0)//结束传递数据的条件
			{
				break;
			}
				}

		close(pipefd[1]);//关闭管道文件的写端
		wait(NULL);//阻塞回收子进程
	}
	else if(pid==0)//子进程
	{
		char rbuf[100]="";
		while(1)
		{
			bzero(rbuf,sizeof(rbuf));
			read(pipefd[0],rbuf,sizeof(rbuf));//从管道文件中读取内容
			if(strcmp(rbuf,"end")==0)
			{
				break;
			}
			printf("从管道文件中读取的内容:%s\n",rbuf);
		}
		close(pipefd[0]);
		exit(EXIT_SUCCESS);//退出子进程
	}
	else
	{
		perror("fork error");
		return -1;
	}

	return 0;
}

 5> 将有名管道的代码实现重新敲一遍

创建管道文件的代码:

#include <myhead.h>	

int main(int argc, const char *argv[])
{
	//创建一个管道文件
	if(mkfifo("./管道文件",0664)==-1)
	{
		perror("mkfifo error");
		return -1;
	}
	getchar();//阻塞,实现多次输入和输出
	system("rm 管道文件");
	return 0;
}

传输源文件代码:

#include <myhead.h>	

int main(int argc, const char *argv[])
{
	//以只写的形式打开管道文件
	int wfd=-1;
	if((wfd=open(argv[1],O_WRONLY))==-1)
	{
		perror("open error");
		return -1;
	}
	char wbuf[1024];
	while(1)
	{
		printf("请输入要传输的内容:");
		fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
		wbuf[strlen(wbuf)-1]='\0';
		//将传输的内容写进管道中
		write(wfd,wbuf,sizeof(wbuf));
		if(strcmp(wbuf,"end")==0)//结束传输数据条件
		{
			break;
		}
	}
	close(wfd);//关闭管道文件
	return 0;
}

接收文件代码:

#include <myhead.h>	

int main(int argc, const char *argv[])
{
	//以只读的形式打开管道文件
	int rfd=-1;
	if((rfd=open(argv[1],O_RDONLY))==-1)
	{
		perror("open error");
		return -1;
	}
	char rbuf[1024];
	while(1)
	{
		bzero(rbuf,sizeof(rbuf));//清空数组
		//读取管道中的文件
		read(rfd,rbuf,sizeof(rbuf));
		if(strcmp(rbuf,"end")==0)//结束传输数据条件
		{
			break;
		}
		//将从管道中读取的数据输出到终端
		printf("从管道文件中读取的内容:%s\n",rbuf);
	}
	close(rfd);//关闭管道文件

	return 0;
}

 6> 使用有名管道完成两个进程的相互通信(提示:可以使用多进程或多线程完成)

创建管道文件代码

#include <myhead.h>	

int main(int argc, const char *argv[])
{
	//创建两个管道文件
	if(mkfifo("./管道文件1",0664)==-1)
	{
		perror("mkfifo error");
		return -1;
	}
	if(mkfifo("./管道文件2",0664)==-1)
	{
		perror("mkfifo error");
		return -1;
	}

	getchar();//阻塞,实现多次输入和输出
	system("rm 管道文件1");
	system("rm 管道文件2");
	return 0;
}

 用户1代码:

#include <myhead.h>	


int main(int argc, const char *argv[])
{
	 pid_t pid = fork();
	if(pid<0)
	{
		perror("fork error");
	}
	else if(pid==0)//子进程读
	{
		//以只读的形式打开管道文件2
		int rfd=-1;
		if((rfd=open(argv[2],O_RDONLY))==-1)
		{
			perror("open error");
			return -1;
		}
		char rbuf[1024];
		while(1)
		{
			bzero(rbuf,sizeof(rbuf));//清空数组
			//读取管道中的文件
			read(rfd,rbuf,sizeof(rbuf));
			if(strcmp(rbuf,"end")==0)//结束传输数据条件
			{
				close(rfd);//关闭管道文件
				break;
			}
			//将从管道2中读取的数据输出到终端
			printf("从管道文件中读取的内容:%s\n",rbuf);
		}
	}
	else//父进程写
	{
		//以只写的形式打开管道文件1
		int wfd=-1;
		if((wfd=open(argv[1],O_WRONLY))==-1)
		{
			perror("open error");
			return -1;
		}
		char wbuf[1024];
		while(1)
		{
			fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
			wbuf[strlen(wbuf)-1]='\0';
			//将传输的内容写进管道中
			write(wfd,wbuf,sizeof(wbuf));
			if(strcmp(wbuf,"end")==0)//结束传输数据条件
			{
				close(wfd);
				break;
			}
		}
	}
	return 0;
}

 用户2代码:

#include <myhead.h>	


int main(int argc, const char *argv[])
{
	pid_t	pid = fork();
	if(pid<0)
	{
		perror("fork error");
	}
	else if(pid==0)//子进程读
	{
		//以只读的形式打开管道文件1
		int rfd=-1;
		if((rfd=open(argv[1],O_RDONLY))==-1)
		{
			perror("open error");
			return -1;
		}
		char rbuf[1024];
		while(1)
		{
			bzero(rbuf,sizeof(rbuf));//清空数组
			//读取管道中的文件
			read(rfd,rbuf,sizeof(rbuf));
			if(strcmp(rbuf,"end")==0)//结束传输数据条件
			{
				close(rfd);//关闭管道文件
				break;
			}
			//将从管道中1读取的数据输出到终端
			printf("从管道文件中读取的内容:%s\n",rbuf);
		}
	}
	else//父进程写
	{
		//以只写的形式打开管道文件2
		int wfd=-1;
		if((wfd=open(argv[2],O_WRONLY))==-1)
		{
			perror("open error");
			return -1;
		}
		char wbuf[1024];
		while(1)
		{	
			fgets(wbuf,sizeof(wbuf),stdin);//从终端获取传输内容
			wbuf[strlen(wbuf)-1]='\0';
			//将传输的内容写进管道中
			write(wfd,wbuf,sizeof(wbuf));
			if(strcmp(wbuf,"end")==0)//结束传输数据条件
			{
				close(wfd);//关闭管道文件
				break;
			}
		}
	}
	return 0;
}

 思维导图:

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

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

相关文章

Liunx使用nginx和http搭建yum-server仓库

文章目录 1. yum-server的搭建方式2. nginx搭建yum-server仓库2.1. 安装配置nginx2.2 配置yum-server的rpm2.3. 同步yum源相关包2.3.1 rsync同步源3.3.1 reposync同步源 2.4. 配置客户端访问yum配置2.5. 验证测试 3. http服务搭建yum-server仓库3.1. 安装配置http3.2 配置yum-s…

代码随想录算法训练营第一天

● 今日学习的文章链接和视频链接 ● 自己看到题目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整个数组是 左闭右闭区间 [ ] left指针指向数组开始下标&#xff0c; right 指针指向数组最后下表nums.size()-1, mid为 (leftright) /2循环条件 left<rightnu…

论文精读--Noisy Student

一个 EfficientNet 模型首先作为教师模型在标记图像上进行训练&#xff0c;为 300M 未标记图像生成伪标签。然后将相同或更大的 EfficientNet 作为学生模型并结合标记图像和伪标签图像进行训练。学生网络训练完成后变为教师再次训练下一个学生网络&#xff0c;并迭代重复此过程…

unity学习(34)——角色选取界面(跨场景坑多)

先把SelectMenu中的camera的audio listener去掉。 现在还是平面&#xff0c;直接在camera下面添加两个panel即可&#xff0c;应该是用不到canvas了&#xff0c;都是2D的UI。 加完以后问题来了&#xff0c;角色选择界面的按钮跑到主界面上边了&#xff0c;而且现在账号密码都输…

国外创意品牌案例:英国北方铁路公司发布“Try the train”活动

近期&#xff0c;英国北方铁路公司&#xff08;Northern Trains&#xff09;发起了一项名为“Try the train” 的活动&#xff0c;旨在帮助那些对火车感到恐惧的人在搭乘火车时感到更舒适&#xff0c;以解锁公司业务新的增长领域&#xff0c;吸引更多的人在通勤、上学、出游、参…

【蓝桥杯单片机入门记录】静态数码管

目录 一、数码管概述 &#xff08;1&#xff09;认识数码管 &#xff08;2&#xff09;数码管的工作原理 &#xff08;3&#xff09;LED数码管驱动方式-静态显示 二、数码管电路图 三、静态数码管显示例程 &#xff08;1&#xff09;例程1&#xff1a;数码管显示某一位&a…

发布 rust 源码包 (crates.io)

rust 编程语言的包 (或者 库, library) 叫做 crate, 也就是软件中的一个组件. 一个完整的软件通常由多个 crate 组成, rust 编译器 (rustc) 一次编译一整个 crate, 不同的 crate 可以同时并行编译. rust 官方有一个集中发布开源包的网站 crates.io. 发布在这上面的 crate 可以…

个性化纹身设计,Midjourney带你探索独一无二的艺术之美

hello,大家好&#xff0c;欢迎回来。 在当今社会&#xff0c;纹身已经变得非常常见。 在寻求与众不同的个性化纹身时&#xff0c;你是否曾经为了找不到独特的设计而苦恼&#xff1f; 现在&#xff0c;Midjourney将为你打开一扇全新的艺术之门&#xff0c;引领你探索纹身设计…

LaWGPT—基于中文法律知识的大模型

文章目录 LaWGPT&#xff1a;基于中文法律知识的大语言模型数据构建模型及训练步骤两个阶段二次训练流程指令精调步骤计算资源 项目结构模型部署及推理 LawGPT_zh&#xff1a;中文法律大模型&#xff08;獬豸&#xff09;数据构建知识问答模型推理训练步骤 LaWGPT&#xff1a;基…

vue:find查找函数实际开发的使用

find的作用&#xff1a; find 方法主要是查找数组中的属性&#xff0c;会遍历数组&#xff0c;对每一个元素执行提供的函数&#xff0c;直到找到使该函数返回 true 的元素。然后返回该元素的值。如果没有元素满足测试函数&#xff0c;则返回 undefined。 基础使用&#xff1a…

Java入门-可重入锁

可重入锁 什么是可重入锁? 当线程获取某个锁后&#xff0c;还可以继续获取它&#xff0c;可以递归调用&#xff0c;而不会发生死锁&#xff1b; 可重入锁案例 程序可重入加锁 A.class,没有发生死锁。 sychronized锁 package com.wnhz.lock.reentrant;public class Sychroniz…

Stable Diffusion 模型分享:Indigo Furry mix(人类与野兽的混合)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

HQYJ 2024-2-21 作业

复习课上内容&#xff08;已完成&#xff09;结构体字节对齐&#xff0c;64位没做完的做完&#xff0c;32位重新都做一遍&#xff0c;课上指定2字节对齐的做一遍&#xff0c;自己验证&#xff08;已完成&#xff09;两种验证大小端对齐的代码写一遍复习指针内容&#xff08;已完…

c++:蓝桥杯的基础算法2(构造,模拟)+练习巩固

目录 构造 构造的基础概念&#xff1a; 模拟 练习1&#xff1a;扫雷 练习2&#xff1a;灌溉 练习3&#xff1a;回文日期 构造 构造的基础概念&#xff1a; 构造算法是一种用于解决特定问题的算法设计方法。在C语言中&#xff0c;构造算法通常涉及到创建一个函数或类来实…

软考-中级-系统集成2023年综合知识(一)

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 软考中级专栏回顾 专栏…

adb-连接模拟器和真机操作

目录 1. 连接模拟器&#xff08;夜神模拟器示例&#xff09; 1.1 启动并连接模拟器 1.2 开启调试模式 2. USB连接真机调试 2.1 usb数据线连接好电脑&#xff0c;手机打开调试模式 2.2 输入adb devices检测手机 3. Wifi连接真机调试 3.1 USB连接手机和电脑 3.2 运行 adb…

世界顶级名校计算机专业学习使用教材汇总

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IauYk2cGjEyljid0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

第四十一回 还道村受三卷天书 宋公明遇九天玄女-python创建临时文件和文件夹

宋江想回家请老父亲上山&#xff0c;晁盖说过几天带领山寨人马一起去。宋江还是坚持一个人去。 宋江到了宋家村&#xff0c;被两个都头和捕快们追捕&#xff0c;慌不择路&#xff0c;躲进了一所古庙。一会儿&#xff0c;听见有人说&#xff1a;小童奉娘娘法旨&#xff0c;请星主…

深度学习神经网络实战:多层感知机,手写数字识别

目的 利用tensorflow.js训练模型&#xff0c;搭建神经网络模型&#xff0c;完成手写数字识别 设计 简单三层神经网络 输入层 28*28个神经原&#xff0c;代表每一张手写数字图片的灰度隐藏层 100个神经原输出层 -10个神经原&#xff0c;分别代表10个数字 代码 // 导入 Ten…

基于FPGA的I2C接口控制器(包含单字节和多字节读写)

1、概括 前文对IIC的时序做了详细的讲解&#xff0c;还有不懂的可以获取TI的IIC数据手册查看原理。通过手册需要知道的是IIC读、写数据都是以字节为单位&#xff0c;每次操作后接收方都需要进行应答。主机向从机写入数据后&#xff0c;从机接收数据&#xff0c;需要把总线拉低来…