IO进程线程day

1.实现互斥机制

 

#include <head.h>

char buf[128];            //全局数组,临界资源

//1、创建一个互斥锁
pthread_mutex_t mutex;

//定义分支线程
void *task(void *arg)
{
    while(1)
    {
        //3、获取锁资源
        pthread_mutex_lock(&mutex);

        printf("分支线程中:buf = %s\n", buf);
        strcpy(buf, "I love China\n");

        //4、释放锁资源
        pthread_mutex_unlock(&mutex);
    }
}


int main(int argc, const char *argv[])
{
    //定义线程号变量
    pthread_t tid;

    //2、初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    //创建线程
    if(pthread_create(&tid, NULL, task, NULL) != 0)
    {
        printf("tid create error\n");
        return -1;
    }

    //主线程
    while(1)
    {
        //3、获取锁资源
        pthread_mutex_lock(&mutex);

        printf("主线程中buf = %s\n", buf);       //访问临界资源
        strcpy(buf, "hello world\n");  

        //4、释放锁资源
        pthread_mutex_unlock(&mutex);
    }
    


    pthread_join(tid, NULL);         //阻塞回收线程资源
    //5、销毁锁资源
    pthread_mutex_destroy(&mutex);

    return 0;
}

2.实现同步机制

#include <head.h>

//1、创建一个无名信号量
sem_t sem;

//生产者线程
void *task1(void *arg)
{
    while(1)
    {
        sleep(2);
        printf("我生产了一辆特斯拉\n");

        //4、释放资源
        sem_post(&sem);
    }
}

//消费者线程
void *task2(void *arg)
{
    while(1)
    {
        //3、申请资源,如果没有资源,则在该处阻塞
        sem_wait(&sem);

        printf("我消费了一辆特斯拉\n");
    }
}

int main(int argc, const char *argv[])
{
    //创建两个线程
    pthread_t tid1,tid2;

    //2、初始化无名信号量
    sem_init(&sem, 0, 0);
    //第一个0:表示用于线程之间的通信
    //第二个0:表示value初始值为0

    //创建生产者线程
    if(pthread_create(&tid1, NULL, task1, NULL) != 0)
    {
        printf("tid1 create error\n");
        return -1;
    }
    //创建消费者线程
    if(pthread_create(&tid2, NULL, task2, NULL) != 0)
    {
        printf("tid2 create error\n");
        return -1;
    }


    //主线程回收资源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    //5、销毁无名信号量
    sem_destroy(&sem);

    return 0;
}

3.使用三个线程完成两个文件的拷贝,线程1完成拷贝前一半,线程2完成拷贝后一半,主线程回收两个分支线程的资源

  1 #include <head.h>
  2 sem_t sem;
  3 struct Info
  4 {
  5     int fd1;
  6     int fd2;
  7     int size;
  8 };
  9
 10 void *task1(void *buf)
 11 {
 12     //不断得将源文件中的内容读出,并写入的目标文件中                                                                                                                                                       
 13     //直到源文件读取一半结束
 14     char buf1[1] = "";
 15     int count=0;
 16     lseek(((struct Info*)buf)->fd1,0,SEEK_SET);
 17     while(1)
 18     {
 19         memset(buf1, 0, sizeof(buf1));    //将容器清空
 20         int res = read(((struct Info*)buf)->fd1, buf1, sizeof(buf1));   //从源文件中读取数据
 21         count+=res;
 22         //对读取的数据个数进行判断
 23         if(count>((struct Info*)buf)->size/2)
 24         {
 25             break;
 26         }
 27         write(((struct Info*)buf)->fd2, buf1, res);     //将数据写入目标文件
 28     }sem_post(&sem);
 29     pthread_exit(NULL);
 30 }
 31 void *task2(void *buf)
 32 {
 33     sem_wait(&sem);
 34     lseek(((struct Info*)buf)->fd1,(((struct Info *)buf)->size)/2,SEEK_SET);
 35     //不断得将源文件中的内容读出,并写入的目标文件中
 36     //直到源文件读取后一半结束
 37     char buf2[128] = "";
 38     while(1)
 39     {
 40         memset(buf2, 0, sizeof(buf2));    //将容器清空
 41         int res = read(((struct Info *)buf)->fd1, buf2, sizeof(buf2));   //从源文件中读取数据
 42         //对读取的数据个数进行判断
 43         if(res==0)
 44         {
 45             break;
 46         }
 47         write(((struct Info*)buf)->fd2, buf2, res);     //将数据写入目标文件
 48     }
 49     pthread_exit(NULL);
 50 }
 51 int main(int argc, const char *argv[])
 52 {
 53     //判断传入的文件个数
 54     if(argc != 3)
 55     {
 56         printf("input file error\n");
 57         printf("usage:./a.out srcfile dstfile\n");
 58         return -1;
 59     }
 60     //定义文件描述符变量
 61     int fd1, fd2;
 62     //以只读的形式打开源文件
 63     if((fd1 = open(argv[1], O_RDONLY)) ==-1)
 64     {
 65         perror("open srcfile error");
 66         return -1;
 67     }
 68     //以只写的形式打开目标文件
 69     if((fd2 = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0664)) ==-1)
 70     {
 71         perror("open dstfile error");
 72         return -1;
 73     }
 74     sem_init(&sem, 0, 0);
 75     unsigned int size;
 76     size = lseek(fd1, 0, SEEK_END);
 77     struct Info buf = {fd1, fd2, size};
 78     //定义一个线程号变量
 79     pthread_t tid1,tid2;
 80     //创建出一个分支线程
 81     if(pthread_create(&tid1, NULL, task1, &buf) != 0)
 82     {
 83         printf("tid create error\n");
 84         return -1;
 85     }
 86     if(pthread_create(&tid2, NULL, task2, &buf) != 0)
 87     {
 88         printf("tid create error\n");
 89         return -1;
 90     }
 91     pthread_join(tid1, NULL);
 92     pthread_join(tid2, NULL);
 93     sem_destroy(&sem);
 94     close(fd1);
 95     close(fd2);
 96     return 0;
 97 }

4.使用三个线程完成:线程1输出字符'A',线程2输出字符'B',线程3输出字符'C',要求输出结果为:ABCABCABCABCABC...

#include <head.h>
sem_t sem1,sem2,sem3;//无名信号量

void *task1(void *arg)
{
	while(1)
	{
		sem_wait(&sem1);//询问当前任务的无名信号量(下同)
		putchar('A');
		fflush(stdout);//刷新缓冲区(下同)
		sleep(1);
		sem_post(&sem2);//将下一个任务的无名信号量改变为1(下同)
	}
}
void *task2(void *arg)
{
	while(1)
	{
		sem_wait(&sem2);
		putchar('B');
		fflush(stdout);
		sleep(1);
		sem_post(&sem3);
	}
}
void *task3(void *arg)
{
	while(1)
	{
		sem_wait(&sem3);
		putchar('C');
		fflush(stdout);
		sleep(1);
		sem_post(&sem1);
	}
}
int main(int argc, const char *argv[])
{
	//无名信号量初始化
	sem_init(&sem1,0,1);
	sem_init(&sem2,0,0);
	sem_init(&sem3,0,0);
	//定义三个线程
	pthread_t tid1,tid2,tid3;
	if(pthread_create(&tid1,NULL,task1,NULL)!=0)
	{
		printf("error1\n");
		return -1;
	}
	if(pthread_create(&tid2,NULL,task2,NULL)!=0)
	{
		printf("error2\n");
		return -1;
	}
	if(pthread_create(&tid3,NULL,task3,NULL)!=0)
	{
		printf("error3\n");
		return -1;
	}
	//进程收尸
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);
	return 0;
}

 

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

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

相关文章

字节跳动机器人研究团队:用大规模视频数据训练GR-1,机器人轻松应对复杂任务

最近 GPT 模型在 NLP 领域取得了巨大成功。GPT 模型首先在大规模的数据上预训练&#xff0c;然后在特定的下游任务的数据上微调。大规模的预训练能够帮助模型学习可泛化的特征&#xff0c;进而让其轻松迁移到下游的任务上。 但相比自然语言数据&#xff0c;机器人数据是十分稀…

【学习笔记】1、数字逻辑概论

1.1 数字信号 数字信号&#xff0c;在时间和数值上均是离散的。数字信号的表达方式&#xff1a;二值数字逻辑和逻辑电平描述的数字波形。 &#xff08;1&#xff09; 数字波形的两种类型 数值信号又称为“二值信号”。数字波形又称为“二值位形图”。 什么是一拍 一定的时…

最新ChatGPT网站系统源码+详细搭建部署教程+Midjourney绘画AI绘画

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

Java学习苦旅(二十三)——二叉搜索树

本篇博客将详细讲解二叉搜索树。 文章目录 二叉搜索树概念操作查找插入删除 性能分析 结尾 二叉搜索树 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -全局异常统一处理实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

Packet Tracer - Configure AAA Authentication on Cisco Routers

Packet Tracer - 在思科路由器上配置 AAA 认证 地址表 目标 在R1上配置本地用户账户&#xff0c;并使用本地AAA进行控制台和vty线路的身份验证。从R1控制台和PC-A客户端验证本地AAA身份验证功能。配置基于服务器的AAA身份验证&#xff0c;采用TACACS协议。从PC-B客户端验证基…

LeetCode 2807. 在链表中插入最大公约数【链表,迭代,递归】1279

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Java多线程技术11——ThreadPoolExecutor类的使用1

1 概述 ThreadPoolExecutor类可以非常方便的创建线程池对象&#xff0c;而不需要程序员设计大量的new实例化Thread相关的代码。 2 队列LinkedBlockingQueue的使用 public class Test1 {public static void main(String[] args) {LinkedBlockingQueue queue new LinkedBlocki…

LeetCode-移动零(283)

题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路&#xff1a; 这里的思路跟以前做过的去重复数字的思路有点像&…

字符输入输出 C语言xdoj16

问题描述&#xff1a; 通过键盘输入5个大写字母&#xff0c;输出其对应的小写字母&#xff0c;并在末尾加上“&#xff01;”。 输入说明&#xff1a; 5个大写字母通过键盘输入&#xff0c;字母之间以竖线“|”分隔。 输出说明&#xff1a; 输出5个大写字母对应的小写字母&…

多线程模板应用实现(实践学习笔记)

出处&#xff1a;B站码出名企路 个人笔记&#xff1a;因为是跟着b站的教学视频以及文档初步学习&#xff0c;可能存在诸多的理解有误&#xff0c;对大家仅供借鉴&#xff0c;参考&#xff0c;然后是B站up阳哥的视频&#xff0c;我是跟着他学。大家有兴趣的可以到b站搜索。加油…

webpack的性能优化(一)——分包优化

1.什么是分包&#xff1f;为什么要分包&#xff1f; 默认情况下&#xff0c;Webpack 会将所有代码构建成一个单独的包&#xff0c;这在小型项目通常不会有明显的性能问题&#xff0c;但伴随着项目的推进&#xff0c;包体积逐步增长可能会导致应用的响应耗时越来越长。归根结底这…

【Linux】进程信号——进程信号的概念和介绍、产生信号、四种产生信号方式、阻塞信号、捕捉信号、阻塞和捕捉信号的函数

文章目录 进程信号1.进程信号的概念和介绍2.产生信号2.1通过终端按键产生信号2.2 调用系统函数向进程发信号2.3 由软件条件产生信号2.4硬件异常产生信号 3.阻塞信号3.1信号在内核中的表示3.2信号集操作函数3.3sigprocmask 4.捕捉信号4.1内核如何实现信号的捕捉4.2 sigaction 进…

【AI视野·今日Robot 机器人论文速览 第七十一期】Fri, 5 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Fri, 5 Jan 2024 Totally 11 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Machine Learning in Robotic Ultrasound Imaging: Challenges and Perspectives Authors Yuan Bi, Zhongliang Jiang, Felix D…

线性代数 --- 矩阵行列式的性质

Determinant det A|A| 矩阵的行列式是一个数&#xff0c;这个数能够反应一些关于矩阵的信息。行列式只对方阵有效。 若矩阵A为&#xff1a; 则A的行列式为&#xff1a; 性质1&#xff1a; 单位矩阵的行列式等于1 性质2&#xff1a;行与行之间的交换会改变det的正负号 以2x2单位…

Mybatis入门源码二:sql执行

后面开始分析sql执行的源码流程也就是这一部分 一、factory.openSession() 重点关注configuration.newExecutor这个方法&#xff0c;获取事务处理器比较简单&#xff0c;就是获取一个jdbc的事务管理器。 这个方法通过传入的执行器类型来创建不同的执行器&#xff0c;有simp…

x-cmd pkg | trdsql - 能对 CSV、LTSV、JSON 和 TBLN 执行 SQL 查询的工具

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 trdsql 是一个使用 sql 作为 DSL 的强大工具: 采用 SQL 对 CSV、LTSV、JSON 和 TBLN 文件执行查询与 MySQL&#xff0c;Postgresql&#xff0c;Sqlite 的 Driver 协同&#xff0c;可以实现对应数据库的表与文件的 JO…

安全基础~信息搜集3

文章目录 知识补充APP信息搜集php开发学习理解漏洞 知识补充 端口渗透总结 python Crypto报错&#xff1a;https://blog.csdn.net/five3/article/details/86160683 APP信息搜集 1. AppInfoScanner 移动端(Android、iOS、WEB、H5、静态网站)信息收集扫描工具 使用教程 演示&…

超维空间M1无人机使用说明书——21、基于opencv的人脸识别

引言&#xff1a;M1型号无人机不仅提供了yolo进行物体识别&#xff0c;也增加了基于opencv的人脸识别功能包&#xff0c;仅需要启动摄像头和识别节点即可 链接: 源码链接 一、一键启动摄像头和人脸识别节点 roslaunch robot_bringup bringup_face_detect.launch无报错&#…

解决ImportError: Failed to import test module: sys.__init__

解决ImportError: Failed to import test module: sys.init 背景 学习通过文件夹执行测试脚本时&#xff0c;出现了错误&#xff1a;ImportError: Failed to import test module: sys.__init__ 解决过程 根据报错信息&#xff1a;sys is not a package大胆猜测可能是文件名…
最新文章