day05-进程通信

news2024/11/14 15:43:56

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

代码:

#include<myhead.h>

int num=520;//临界资源

//1.创建互斥锁
pthread_mutex_t fastmutex;
       
//定义任务函数
void *task1(void *arg){
    printf("1111111\n");

    //3.临界区上面获取锁资源(上锁)
    pthread_mutex_lock(&fastmutex);

    num=1314;
    sleep(3);
    printf("task1:num = %d\n",num); //1314

    //4. 释放锁资源
    pthread_mutex_unlock(&fastmutex);
}

void *task2(void *arg){
    printf("2222222\n");

    pthread_mutex_lock(&fastmutex);

    num++;      //521
    sleep(1);   //休眠时任务1执行到赋值语句
    printf("task2:num = %d\n",num);

    pthread_mutex_unlock(&fastmutex);
}

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

    //2.初始化互斥锁
    pthread_mutex_init(&fastmutex,NULL);

    //线程创建
    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;
    }

    printf("tid1:%#lx, tid2:%#lx\n",tid1,tid2);

    //回收资源
    if(pthread_join(tid1,NULL)==0)
        printf("tid1回收成功\n");
    if(pthread_join(tid2,NULL)==0)
        printf("tid2回收成功\n");

    //5. 销毁锁资源
    pthread_mutex_destroy(&fastmutex);
    
    return 0;
}

结果:

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

代码:

#include<myhead.h>

//创建无名信号了
sem_t sem;

//定义生产者线程
void *task1(void *arg){
    printf("1111111\n");
    
    int num= 5;
    while(num--){
        //3.申请资源
    //    sem_wait(&sem);

        sleep(1);
        printf("我生产了一辆车\n");

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

    }
    pthread_exit(NULL);
}

//定义消费者线程
void *task2(void *arg){
    printf("2222222\n");

    int num= 5;
    while(num--){
        //3.申请资源
        sem_wait(&sem);

        printf("我消费了一辆车\n");

         //4.释放资源
    //    sem_post(&sem);
    }
    pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
    //初始化无名信号量
    sem_init(&sem,0,0);
    //第一个0:表示用于线程的同步
    //第二个0:表示初始资源为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;
    }

    printf("tid1:%#lx, tid2:%#lx\n",tid1,tid2);

    //回收资源
    if(pthread_join(tid1,NULL)==0)
        printf("tid1回收成功\n");
    if(pthread_join(tid2,NULL)==0)
        printf("tid2回收成功\n");

    //释放无名信号量
    sem_destroy(&sem);

    return 0;
}

结果:

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

代码:

#include<myhead.h>

//1. 定义条件变量
pthread_cond_t cond;

//11. 创建互斥锁
pthread_mutex_t fastmutex;

//定义生产者线程
void *task1(void *arg){

    int num= 5;
    while(num--){

        sleep(1);
        printf("%#lx:生产了一辆车\n",pthread_self());

        //3. 唤醒一个消费者
        pthread_cond_signal(&cond);
    }
    pthread_exit(NULL);
}

//定义消费者线程
void *task2(void *arg){

    //33.临界区上面获取锁资源(上锁)
    pthread_mutex_lock(&fastmutex);

    //4. 进入等待队列
    pthread_cond_wait(&cond,&fastmutex);


    printf("%#lx:消费了一辆车\n",pthread_self());

    //54. 释放锁资源
    pthread_mutex_unlock(&fastmutex);

    pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
    //2. 初始化无名信号量
    pthread_cond_init(&cond,NULL);
    
    //22. 初始化互斥锁
    pthread_mutex_init(&fastmutex,NULL);

    //创建2个线程,分别是生产者和消费者
    pthread_t tid1,tid2,tid3,tid4,tid5,tid6;
    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;
    }    
    if(pthread_create(&tid5,NULL,task2,NULL)!=0){
        printf("tid5 create error\n");
        return 0;
    }
    if(pthread_create(&tid6,NULL,task2,NULL)!=0){
        printf("tid6 create error\n");
        return 0;
    }
    printf("tid1:%#lx, tid2:%#lx, tid3:%#lx\ntid4:%#lx, tid5:%#lx, tid6:%#lx\n",tid1,tid2,tid3,tid4,tid5,tid6);

    //回收资源
    if(pthread_join(tid1,NULL)==0)
        printf("tid1回收成功\n");
    if(pthread_join(tid2,NULL)==0)
        printf("tid2回收成功\n");
    if(pthread_join(tid3,NULL)==0)
        printf("tid3回收成功\n");
    if(pthread_join(tid4,NULL)==0)
        printf("tid4回收成功\n");
    if(pthread_join(tid5,NULL)==0)
        printf("tid5回收成功\n");
    if(pthread_join(tid6,NULL)==0)
        printf("tid6回收成功\n");


    //5. 销毁条件变量
    pthread_cond_destroy(&cond);

    //55. 销毁锁资源
    pthread_mutex_destroy(&fastmutex);
    return 0;
}

结果:

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

代码:

#include<myhead.h>

int main(int argc, char const *argv[])
{
    //创建管道文件,并返回该管道文件的文件描述符(最小位分配原则)
    int pipefd[2]={0};
    if(pipe(pipefd)==1)
        PRINT_ERR("");
    printf("pipedf[0]=%d,pipefd[1]=%d\n",pipefd[0],pipefd[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)
        {
            //清空rbuf内容
            bzero(rbuf,sizeof(rbuf));

            //从管道文件中读取数据
            read(pipefd[0],rbuf,sizeof(rbuf));

            //输出rbuf的数据
            printf("父进程传来的数据为:%s\n",rbuf);

            //对读取的数据进行判断
            if(strcmp(rbuf,"quit")==0)
                break;
        }

        //关闭管道的读端
        close(pipefd[0]);

        exit(EXIT_SUCCESS);     //退出进程
    }else
        PRINT_ERR("");    
    return 0;
}

结果:

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

代码:

#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;
}
#include<myhead.h>

int main(int argc, char const *argv[])
{
    //打开管道文件
    int wfd=1;

    //以只写的形式打开文件
    if((wfd=open("./myfifo",O_WRONLY))==-1)
        PRINT_ERR("");

    //定义容器
    char wbuf[128]="";
    while(1)
    {
        bzero(wbuf,sizeof(wbuf));   //清空数组内容
        
        fgets(wbuf,sizeof(wbuf),stdin);     //从终端输入数据
        wbuf[strlen(wbuf)-1]=0;

            //将数据写入管道文件中
         write(wfd,wbuf,strlen(wbuf));

            //对写入的数据进行判断
            if(strcmp(wbuf,"quit")==0)
                break;
    }
    return 0;
}
#include<myhead.h>

int main(int argc, char const *argv[])
{
    //打开管道文件
    int wfd=1;

    //以只读的形式打开文件
    if((wfd=open("./myfifo",O_RDONLY))==-1)
        PRINT_ERR("");

    //定义容器
    char rbuf[128]="";
    while(1)
    {
        
        //清空rbuf内容
        bzero(rbuf,sizeof(rbuf));
    
        //将数据写入管道文件中
        read(wfd,rbuf,sizeof(rbuf));

        //输出rbuf的数据
        printf("父进程传来的数据为:%s\n",rbuf);

        //对读取的数据进行判断
        if(strcmp(rbuf,"quit")==0)
            break;
    }
    return 0;
}

结果:

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

代码:

管道文件创建

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //创建一个管道文件
    if(mkfifo("./myfifo1", 0664) == -1)
    {
        perror("mkfifo1 error");
        return -1;
    }
    if(mkfifo("./myfifo2", 0664) == -1)
    {
        perror("mkfifo2 error");
        return -1;
    }
    getchar();       //阻塞

    system("rm myfifo1");
    system("rm myfifo2");

    return 0;
}

线程:

#include<myhead.h>

int main(int argc, char const *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("这里是1号机,请输入>>>");
                fgets(wbuf, sizeof(wbuf), stdin);
                wbuf[strlen(wbuf)-1] = 0;

                //将数据写入有名管道
                write(wfd, wbuf, strlen(wbuf));

                //判断结果
                if(strcmp(wbuf,"quit") == 0)
                    break;

        }
            //关闭文件
        close(wfd);          
//        wait(NULL);  //阻塞回收子进程资源
    }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("\t\t\t\t\t1号机收到的数据为:%s\n", rbuf);

            //判断结果
            if(strcmp(rbuf,"quit") == 0)
                break;

    }

            //关闭文件
            close(rfd);

        exit(EXIT_SUCCESS);     //退出进程
    }else
        PRINT_ERR("");    
    return 0;
}
#include<myhead.h>

int main(int argc, char const *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("\t\t\t\t\t2号机收到的数据为:%s\n", rbuf);

            //判断结果
            if(strcmp(rbuf,"quit") == 0)
                break;


    }

            //关闭文件
        close(rfd); 
 
 //       wait(NULL);
     //   wait(NULL);  //阻塞回收子进程资源
    }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("这里是2号机,请输入>>>");
                fgets(wbuf, sizeof(wbuf), stdin);
                wbuf[strlen(wbuf)-1] = 0;

                //将数据写入管道
                write(wfd, wbuf, strlen(wbuf));

                //判断结果
                if(strcmp(wbuf,"quit") == 0)
                    break;
            
        }

            //关闭文件
        close(wfd);      

        exit(EXIT_SUCCESS);     //退出进程
    }else
        PRINT_ERR("");    
    return 0;
}

结果:

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

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

相关文章

【嵌入式学习】QT-Day2-Qt基础

1> 思维导图 https://lingjun.life/wiki/EmbeddedNote/20QT 2>登录界面优化 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff…

并发编程之深入理解Java线程

并发编程之深入理解Java线程 线程基础知识 线程和进程 进程 程序由指令和数据组成、但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须要将指令加载至CPU、数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的…

项目解决方案:校园云视频平台方案(视频接入、汇聚、联网、分享)

目 录 一、项目需求 二、系统设计方案 三、平台功能 四、案例展示 本方案分四个部分&#xff1a;项目需求、系统设计方案、平台基础功能、案例展示&#xff0c;如下&#xff1a; 一、项目需求 二、系统设计方案 通过AS-V1000视频资源综合管理平台实现监控视频的接入、…

成年人学英语其实有个捷径,但你们都不信

上班了…… 我不想上班&#xff0c;只想躺平&#xff0c;同时银行卡上的余额还能够不断的增加。 当然现阶段肯定是不行的&#xff0c;我仍要靠打工养活自己&#xff0c;而且先要获得第一桶金。 第一桶金在何方&#xff1f;我还不知道&#xff0c;人在迷茫时&#xff0c;就来学英…

docker:Haoop集群

系列文章目录 docker&#xff1a;环境安装 docker:Web迁移 docker:Haoop集群 文章目录 系列文章目录前言一、宿主机选择二、环境准备1.前置技术2.网络环境1. docker网卡2. 分配IP 三、容器互联三、Jdk和Hadoop安装四、分发脚本五、启动Hadoop总结 前言 年前学习了docker的相关…

新疆营盘古城及古墓群安防舱体实施方案

3 总体布局 3.1设计原则 3.1.1执行有效的国家标准、国家军用标准和行业标准&#xff1b; 3.1.2满足指标要求&#xff1b; 3.1.3采用通用化、模块化设计&#xff0c;提高设备可维修性&#xff1b; 3.1.4采用人机工程学知识进行设计&#xff0c;充分考虑安全性。 3.2 总体…

Sora的第一波受害者出现了。

不知道大家最近除了被Sora刷屏之外&#xff0c;有没有被这张图刷屏 我只能说网友太强大了 说实话&#xff0c;我进入舟老师的直播间&#xff0c;每次都是还有3分钟下播&#xff0c;还有6单就拍完 但是10分钟后还在激情逼单&#xff0c;6单之后还有6单 也许在营销学上&#x…

亚马逊工程师严选,超 40 篇 LLM 论文汇总

2023 年&#xff0c;大语言模型依旧是「话题制造机」&#xff0c;不管是 OpenAI 的「宫斗剧」&#xff0c;还是各个大厂的新模型、新产品「神仙打架」&#xff0c;亦或是行业大模型发展的风生水起&#xff0c;都昭示着大语言模型具备巨大的发展空间。花香自引蝶&#xff0c;其实…

LeetCode 算法题 (数组)存在连续3个奇数的数组

问题&#xff1a; 输入一个数组&#xff0c;并输入长度&#xff0c;判断数组中是否存在连续3个元素都是奇数的情况&#xff0c;如果存在返回存在连续3个元素都是奇数的情况&#xff0c;不存在返回不存在连续3个元素都是奇数的情况 例一&#xff1a; 输入&#xff1a;a[1,2,3…

探索Django路由规则(路由匹配、路由命名空间、HTML中的跳转与Django集成、路由传参以及后端重定向)

路由管理&#xff1a; ​ 在实际开发过程中&#xff0c;⼀个Django 项⽬会包含很多的 app &#xff0c;这时候如果我们只在主路由⾥进⾏配置就会显得杂乱⽆章&#xff0c;所以通常会在每个 app ⾥&#xff0c;创建各⾃的 urls.py 路由模块&#xff0c;然后从根路由出发&#x…

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

代码随想录算法训练营第三十八天|509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯。

509. 斐波那契数 题目链接&#xff1a;斐波那契数 题目描述&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c…

2024 高级前端面试题之 计算机通识(基础) 「精选篇」

该内容主要整理关于 计算机通识&#xff08;基础&#xff09; 的相关面试题&#xff0c;其他内容面试题请移步至 「最新最全的前端面试题集锦」 查看。 计算机基础精选篇 一、网络1.1 UDP1.2 TCP1.3 HTTP1.4 DNS 二、数据结构2.1 栈2.2 队列2.3 链表2.4 树2.5 堆 三、算法3.1 时…

阿里云配置服务器详细指南_2024年CPU内存带宽配置选择

阿里云服务器配置怎么选择&#xff1f;根据实际使用场景选择&#xff0c;个人搭建网站可选2核2G配置&#xff0c;访问量大的话可以选择2核4G配置&#xff0c;企业部署Java、Python等开发环境可以选择2核8G配置&#xff0c;企业数据库、Web应用或APP可以选择4核8G配置或4核16G配…

Sora热潮 | 暴雨AI服务器助推大模型向前发展

Sora全球爆火这事还有谁不知道吗&#xff1f; 2月16日&#xff0c; OpenAI发布了一条由视频大模型Sora所自动生成的视频&#xff0c;逼真的视觉效果让其在一夜之间“刷屏”。 一石激起千层浪&#xff0c;Sora的发布让科技从业者&#xff0c;投资圈、影视行业纷纷“炸锅“&…

【双指针】:LCR179.查找总价值为目标值的两个商品

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…

数据结构D3作业

1. 2. 按位插入 void insert_pos(seq_p L,datatype num,int pos) { if(LNULL) { printf("入参为空&#xff0c;请检查\n"); return; } if(seq_full(L)1) { printf("表已满&#xff0c;不能插入\n"); …

Spring 类型转换、数值绑定与验证(二)—PropertyEditor与Conversion

Spring 中&#xff0c;属性类型转换是在将数值绑定到目标对象时完成的。例如在创建ApplicationContext 容器时&#xff0c;将XML配置的bean 转换成Java类型对象&#xff0c;主要是借助了PropertyEditor类&#xff0c;而在Spring MVC 的Controller的请求参数转化为特定类型时&am…

为M系Mac安装Centos

下载镜像 需要使用特殊镜像&#xff0c;官网或国内的arch 镜像源不可安装 https://share.weiyun.com/2qc0S2VV CentOS-7-aarch64-08191738.mpg https://www.aliyundrive.com/s/1DCW2E5EySR 原文链接&#xff1a;https://blog.csdn.net/acdemic964850/article/details/1290565…

ROS问题记录

目前遇到的问题&#xff1a; 1 、包名大写会警告 包名不要出现大写 2、catkin_make前配置环境变量 尤其在更换终端时&#xff0c;一定要再配置一遍环境变量&#xff0c;常见的错误如下 基本上这个错误都是因为没有执行以下命令 source ~/catkinws/devel/setup.bash3、调用…