进程线程间的通信:2024/2/22

作业1:代码实现线程互斥机制

代码:

#include <myhead.h>//临界资源
int num=10;//创建一个互斥锁
pthread_mutex_t mutex;//任务一
void *task1(void *arg)
{//获取锁资源pthread_mutex_lock(&mutex);num=123;sleep(3);printf("task1:num=%d\n",num);//释放锁资源pthread_mutex_unlock(&mutex);//退出线程pthread_exit(NULL);
}
//任务二
void *task2(void *arg)
{//获取锁资源pthread_mutex_lock(&mutex);num++;sleep(1);printf("task2:num=%d\n",num);//释放锁资源pthread_mutex_unlock(&mutex);//退出线程pthread_exit(NULL);
}
/*************************主程序************************/
int main(int argc, const char *argv[])
{//初始化互斥锁pthread_mutex_init(&mutex,NULL);//创建两个线程pthread_t tid1,tid2;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid1 error\n");return -1;}printf("tid1=%#lx tid2=%#lx\n",tid1,tid2);//回收资源pthread_join(tid1,NULL);pthread_join(tid2,NULL);//销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}

效果图:

作业2:代码实现无名信号量的线程同步机制

代码:

#include <myhead.h>//定义一个无名信号量
sem_t sem1;
sem_t sem2;
sem_t sem3;
//任务1
void *task1(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem3);sleep(1);printf("A");fflush(stdout);           //刷新缓冲区//释放资源sem_post(&sem1);}//退出线程pthread_exit(NULL);}
//任务2
void *task2(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem1);sleep(1);printf("B");fflush(stdout);           //刷新缓冲区//释放资源sem_post(&sem2);}//退出线程pthread_exit(NULL);}
//任务3
void *task3(void *arg)
{int num=4;while(num--){//申请资源sem_wait(&sem2);sleep(1);printf("C");fflush(stdout);           //刷新缓冲区//释放资源sem_post(&sem3);}//退出线程pthread_exit(NULL);}
/*********************主程序********************/
int main(int argc, const char *argv[])
{//初始化无名信号量sem_init(&sem1,0,0);sem_init(&sem2,0,0);sem_init(&sem3,0,1);//创建三个线程pthread_t tid1,tid2,tid3;if(pthread_create(&tid1,NULL,task1,NULL) != 0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL) != 0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task3,NULL) != 0){printf("create tid3 error\n");return -1;}//回收资源pthread_join(tid1,NULL);pthread_join(tid2,NULL);pthread_join(tid3,NULL);//销毁无名信号量sem_destroy(&sem1);sem_destroy(&sem2);sem_destroy(&sem3);puts("");return 0;
}

效果图:

作业3:代码实现条件变量的线程同步机制

代码:

#include <myhead.h>
//定义条件变量
pthread_cond_t cond;//定义互斥锁变量
pthread_mutex_t mutex;//生产者
void *task1(void *arg)
{int num=3;while(num--){sleep(1);printf("%#lx:摘了一个苹果\n",pthread_self());//唤醒一个进程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);//创建生产者与消费者线程pthread_t tid1,tid2,tid3,tid4;if(pthread_create(&tid1,NULL,task1,NULL)!=0){printf("create tid1 error\n");return -1;}if(pthread_create(&tid2,NULL,task2,NULL)!=0){printf("create tid2 error\n");return -1;}if(pthread_create(&tid3,NULL,task2,NULL)!=0){printf("create tid3 error\n");return -1;}if(pthread_create(&tid4,NULL,task2,NULL)!=0){printf("create tid4 error\n");return -1;}//回收资源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[128]="";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,"quit")==0){break;}}//关闭管道写端close(pipefd[1]);//等待回收子进程wait(NULL);}else if(pid==0){//子进程进行读操作//关闭管道写端close(pipefd[1]);char rbuf[128]="";while(1){//清空数组内容bzero(rbuf,sizeof(rbuf));//从管道文件中读取数据read(pipefd[0],rbuf,sizeof(rbuf));printf("从父进程传来的数据:%s\n",rbuf);//判断写入的数据if(strcmp(rbuf,"quit")==0){break;}}//关闭管道读端close(pipefd[0]);//退出子进程exit(EXIT_SUCCESS);}else{perror("pid error");return -1;}return 0;
}

效果图:

作业5:代码实现有名管道的通信

代码:

create.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//创建一个管道文件if(mkfifo("./myfifo",0664)==-1){perror("mkfifo error");return -1;}getchar();          //阻塞system("rm myfifo");return 0;
}

snd.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);return 0;
}

rec.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);return 0;
}

效果图:

作业6:使用有名管道完成两个进程的相互通信

(提示:可以使用多进程或多线程完成)

代码:

create.c:

#include <myhead.h>
int main(int argc, const char *argv[])
{//创建两个管道文件if(mkfifo("./myfifo1",0664)==-1){perror("mkfifo error");return -1;}if(mkfifo("./myfifo2",0664)==-1){perror("mkfifo error");return -1;}getchar();          //阻塞system("rm myfifo1");system("rm myfifo2");return 0;
}

snd.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//创建一个进程pid_t pid=fork();if(pid>0){//父进程发送数据//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo1",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);}else if(pid==0){//子进程接收数据//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo2",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);}else{perror("pid error");return -1;}return 0;
}

rec.c:

#include <myhead.h>int main(int argc, const char *argv[])
{//创建一个进程pid_t pid=fork();if(pid>0){//父进程接收数据//打开管道文件int rfd=-1;//以只读形式打开文件if((rfd=open("./myfifo1",O_RDONLY))==-1){perror("open error");return -1;}char rbuf[128]="";while(1){//清空数组bzero(rbuf,sizeof(rbuf));//从管道读取数据read(rfd,rbuf,sizeof(rbuf));//输出结果printf("收到的数据为:%s\n",rbuf);//退出条件if(strcmp(rbuf,"quit")==0){break;}}//关闭文件close(rfd);}else if(pid==0){//子进程发送数据//打开管道文件int wfd=-1;//以只写的形式打开管道文件if((wfd=open("./myfifo2",O_WRONLY))==-1){perror("open error");return -1;}char wbuf[128]="";while(1){//从终端输入数据printf("请输入:");	fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';//将数据写入管道文件write(wfd,wbuf,strlen(wbuf));//结束输入的条件if(strcmp(wbuf,"quit")==0){break;}}//关闭文件close(wfd);}else{perror("pid error");return -1;}return 0;
}

效果图:

作业7:思维导图

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

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

相关文章

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序 PacketSender是一款开源的用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序&#xff0c;作者为dannagle。 其官网地址为&#xff1a;https://packetsender.com/&#xff0c;Github源代码地址&#xff1a;htt…

【AI绘画工具分别有哪些?】

目前有许多AI绘画工具可供选择&#xff0c;以下列举了一些常见的AI绘画工具&#xff1a; 1. DeepArt.io&#xff1a;该工具使用深度学习算法生成艺术风格的图像&#xff0c;并可以将输入图像与指定的艺术风格进行合并。 2. Prisma&#xff1a;这是一款非常流行的AI绘画应用&a…

SQL Server —— While语句循环

一&#xff1a;简介 while 循环是有条件的循环控制语句。满足条件后&#xff0c;再执行循环体中的SQL语句。 while: break, 如果有多条语句可以在while后面添加begin-end。关于while的语法 while(条件) -- begin -- 语句1 -- 语句2 -- break 根据情况是否添加break -- end 二…

leetcode日记(32)字符串相乘

做了很久很久……真的太繁琐了&#xff01;&#xff01; class Solution { public:string multiply(string num1, string num2) {string s;string str;if (num1 "0" || num2 "0") return "0";for(int inum2.size()-1;i>0;i--){int c2num2[…

Open CASCADE学习|全局属性

目录 1、概念解释 质心&#xff1a; 重心&#xff1a; 惯性矩&#xff1a; 惯性矩阵&#xff1a; 主惯性矩&#xff1a; 静态惯性矩&#xff1a; 2、API 1、概念解释 质心&#xff1a; 质心是质量中心的简称&#xff0c;指物质系统上被认为质量集中于此的一个假想点。…

Qt:tabWidget控件

一、tabWidget用来做什么 tabWidget控件用来进行不同控件页面的跳转&#xff0c; 二、控件的一些函数功能 添加一个页面&#xff0c;返回index int addTab(QWidget *widget, const QString &); int addTab(QWidget *widget, const QIcon& icon, const QString &…

pytest教程-11-初识fixture

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了使用allure生成html测试报告的方法&#xff0c;本小节我们讲解一下pytest fixture测试夹具的使用方法。 前言 在做自动化的过程中&#xff0c;编写用例时候需要用到用例的前置和用例的后置&a…

2024年了,抖店还能做吗?适合新手吗?

我是电商珠珠 现在已经24年了&#xff0c;抖店也已经发展了四年了。其中有很多在门外观望的人&#xff0c;还在犹豫不决。认为抖店发展到今天&#xff0c;所有的红利早已在20年的时候就消失殆尽了&#xff0c;特别是没有经验的如果入驻了&#xff0c;既不能享受平台红利&#…

后端程序员入门react笔记(四)-综合运用,写一个小demo

样式模块化 有时候我们会遇到这样的问题&#xff0c;有两个css对一个class声明了样式&#xff0c;这样的话后引入的css会覆盖前面的css样式&#xff0c;导致样式冲突&#xff0c;那么我们怎么解决这种问题呢&#xff0c;我们可以使用样式的模块化&#xff0c;我们起名一个inde…

全栈笔记_浏览器扩展篇(插件开发 - chrome浏览器proxy代理)

代理类型 常用的包括http、https、socks代理 配置权限 要让扩展使用代理接口,需要声明proxy权限: // manifest.json "permissions": ["proxy" ]设置代理服务器 chrome.proxy.settings.set({ scope: ‘regular’, value: 代理配置},回调函数) 代理配…

【前端面经2】京东一面

题目来源&#xff1a;牛客网 自我介绍 动态参数解析的解决方案 对于动态部分使用…args进行接受&#xff0c;可以把动态部分提取成数组 前端安全问题 CDN劫持 内容安全策略CSP 安全沙箱 Iframe 跨站脚本攻击XSS 攻击者通过在目标网站上注入恶意脚本&#xff0c;使之在…

OpenHarmony驱动框架HDF中设备管理服务构建过程详解

前言 如下图&#xff0c;开源鸿蒙系统驱动框架HDF在内核中的实现&#xff0c;可以分为向用户层提供设备服务的管理模块&#xff08;Manager&#xff09;&#xff0c;和实际管理硬件的Host模块。 Manager分为DeviceManageService和 DeviceServiceManage&#xff0c;前者负责提供…

1.WEB渗透测试-前置基础知识-ip地址

ip地址&#xff1a; ip地址指的是互联网协议地址&#xff0c;是IP协议提供的一种统一的地址格式&#xff0c;以每一台联网的主机都有一个对应的ip地址&#xff0c;ip地址也可以理解为分配给用户上网使用的网际协议的设备的数字标签。通俗的来说就是你打电话时候的每个人都有自己…

AIGC 实战:如何使用 Docker 在 Ollama 上离线运行大模型(LLM)

Ollama简介 Ollama 是一个开源平台&#xff0c;用于管理和运行各种大型语言模型 (LLM)&#xff0c;例如 Llama 2、Mistral 和 Tinyllama。它提供命令行界面 (CLI) 用于安装、模型管理和交互。您可以使用 Ollama 根据您的需求下载、加载和运行不同的 LLM 模型。 Docker简介 D…

在Mac上搭建MongoDB环境

最近工作中需要装MongoDB环境&#xff0c;搭建过程中遇到了一些问题&#xff0c;在这里记录一下安装MongoDB环境的方法以及问题的解决方法。有两种安装MongoDB的方法&#xff1a;brew安装和手动安装。 目录 使用Homebrew安装MongoDB 手动安装MongoDB&#xff08;不使用Homebr…

备战蓝桥杯 Day11(滚动数组优化+完全背包)

01背包的滚动数组优化 【题目描述】 经典0—1背包问题,有n个物品&#xff0c;编号为i的物品的重量为w[i]&#xff0c;价值为c[i]&#xff0c;现在要从这些物品中选一些物品装到一个容量为m的背包中&#xff0c;使得背包内物体在总重量不超过m的前提下价值尽量大。 #include&…

python_数据分析_numpy库

一、创建ndarray *ndarray是NumPy中表示数组的重要类型 1、使用np.array()创建 *参数列表&#xff1a;[1,2,3,4] 注&#xff1a;(1)、numpy默认ndarray的所有元素的类型是相同的 ​ (2)、如果传入的数据类型不同&#xff0c;会被按照优先级强制转换为同一类型&#xff0c;其…

vue--两种定时任务cron表达式组件比较选择

背景&#xff1a; 使用vue页面中cron表达式的组件&#xff0c;实现定时任务参数配置。 方案1 vue-cron 安装插件 npm install vue-cron --save 全局引入&#xff0c;修改main.js import Vue from vue import VueCron from vue-cron Vue.use(VueCron);页面配置 html<el-…

Java入门-可重入锁

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

多普勒变化率的应用 与 FPGA

1.多普勒变化率是一个描述波源和观察者相对速度变化的物理量&#xff0c;它与加速度有关。 多普勒效应是指当波源和观察者之间存在相对运动时&#xff0c;观察者接收到的波频率与波源发射的频率之间的差异。这种现象在声波、电磁波等多种波动中都会出现。多普勒变化率通常用来…