进程线程间的通信: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…

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[…

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…

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地址也可以理解为分配给用户上网使用的网际协议的设备的数字标签。通俗的来说就是你打电话时候的每个人都有自己…

在Mac上搭建MongoDB环境

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

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…

linux系统内核升级

1.查看旧版本内核 2.导入密钥 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 3.安装yum源 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm4.启用elrepo-kernel仓库并安装最新内核版本 yum --enablerepoelrepo-kernel install …

一文弄明白KeyedProcessFunction函数

引言 KeyedProcessFunction是Flink用于处理KeyedStream的数据集合&#xff0c;它比ProcessFunction拥有更多特性&#xff0c;例如状态处理和定时器功能等。接下来就一起来了解下这个函数吧 正文 了解一个函数怎么用最权威的地方就是 官方文档 以及注解&#xff0c;KeyedProc…

c++实现栈和队列类

c实现栈和队列类 栈(Stack)Stack示意图Stack.cpp 队列(queue)queue 示意图queue.cpp 栈(Stack) Stack示意图 Stack.cpp #pragma once #include "ListStu.cpp"template<typename T> class Stack { public: /* * void push(T& tDate)* 参数一 &#xff1a;…

记录解决uniapp使用uview-plus在vue3+vite+ts项目中打包后样式不能显示问题

一、背景 从 vue2uview1 升级到 vue3vitetsuview-plus ,uview组件样式打包后不显示&#xff0c;升级前uview 组件是可以正常显示&#xff0c;升级后本地运行是可以正常显示&#xff0c;但是打包发布成H5后uview的组件无法正常显示&#xff0c;其他uniapp自己的组件可以正常显示…

Vue 中 onclick和@click区别

文章目录 一、直接上结论二、验证代码&#xff0c;可直接运行三、点击结果 一、直接上结论 onclick 只能触发 js的原生方法&#xff0c;不能触发vue的封装方法click 只能触发vue的封装方法&#xff0c;不能触发js的原生方法 二、验证代码&#xff0c;可直接运行 <!DOCTYP…

Vue3 + Ts (使用lodash)

安装 npm i --save lodash使用 import _ from lodash⚠️报警告&#xff1a;&#xff01;&#xff01;&#xff01; 此时还需要安装ts声明文件库 npm install types/lodash -D安装之后重启Vscode还是会提示上面的警告&#xff0c;此时还需在tsconfig.ts里面配置 {"c…

快速将excel/word表格转换为web页面(html)的方法

前言 在进行开发企业信息化建设的过程&#xff0c;应该有很多这样的场景&#xff0c;就是将现有的电子表格记录的方式转换为在数据系统中进行网页上报。也就是需要根据当前一直使用的表格制作一个上传这个表格信息的网页&#xff0c;如果要减少系统的使用学习成本&#xff0c;…

leetcode:78.子集

1.树形结构&#xff1a;往后依次取该数字往后的数字&#xff08;前面的不要取&#xff0c;否则子集会重复&#xff09;&#xff1b;每一层递归的结果都要放入结果集&#xff0c;而并非只放叶子节点。 代码实现&#xff1a; #达到了叶子节点&#xff08;终止条件&#xff09; …