TypechoJoeTheme

mmzkyl

操作系统实验三之利用Linux的共享内存通信机制实现两个进程间的通信

mmzkyl博主
2021-09-19
/
0 评论
/
212 阅读
/
656 个字
/
百度已收录
09/19
本文最后更新于2021年09月19日,已超过246天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

操作系统实验三之利用Linux的共享内存通信机制实现三个进程间的通信

前言

​ 编写程序创建三个线程:sender1线程sender2线程receiver线程,三个线程的功能描述如下:

  1. sender1线程:运行函数sender1(),它创建一个消息队列,然后等待用户通过终端输入一串字符,并将这串字符通过消息队列发给receiver线程;可循环发送多个消息,直到用户输入“exit”为止,表示它不再发送消息,最后向receiver线程发送消息“end1”,并且等待receiver的应答(老师告知可以省略这步,所以代码没有体现,sender2同),等到应答消息后,将接收到的应答信息显示在终端屏幕上,结束线程的运行。
  2. sender2线程:运行函数sender2(),共享sender1创建的消息队列,等待用户通过终端输入一串字符,并将这串字符通过消息队列发送给receiver线程;可循环发送多个消息,直到用户输入“exit”为止,表示它不再发送消息,最后向receiver线程发送消息“end2”,并且等待receiver的应答,等到应答消息后,将接收到的应答信息显示在终端屏幕上,结束线程的运行。
  3. receiver线程:运行函数receive(),它通过消息队列接收来自sender1和sender2两个线程的消息,将消息显示在终端屏幕上,当收到内容为“end1”的消息时,就向sender1发送一个应答消息“over1”;当收到内容为“end2”的消息时,就向sender2发送一个应答消息“over2”;消息接受完成后删除消息队列,结束线程的运行。选择合适的信号量机制实现三个线程之间的同步和互斥。

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<sys/msg.h>
#include<semaphore.h>
#include<sys/types.h>
#include<sys/ipc.h>

pthread_t s1,s2,r;
//定义线程

sem_t Write;
sem_t Read;
sem_t mutex_0,mutex_1,mutex_2;
//定义信号量
//mutex_0代表receive的操作权
//mutex_1代表send1操作权
//mutex_2代表send2操作权

int flag_temp;
//切换进程判断所需参数

struct msgbuf{ 
    long mtype ;
    char mtext[100];
};

void *receive(void *arg){
    struct msgbuf buf;
    int flag1 = 1,flag2 = 1;
    for(;1;)
    {
        memset(&buf,0,sizeof(buf));

        sem_wait(&mutex_0);
        sem_wait(&Read);
        //receive需要有操作权并且有Read的权利,才能够读取

        int ret = msgrcv(*(int *)arg,&buf,sizeof(buf.mtext),2,0);
        //接收消息

        if (ret == -1){
            perror("msgrcv error");
            exit(1);
        }
        else{
            printf("receive:%s\n",buf.mtext);
        } 

        if(flag1&&!strncmp(buf.mtext,"end1",4)){
            pthread_cancel(s1);
            flag1--;
        }
        else if(flag2&&!strncmp(buf.mtext,"end2",4)){
            pthread_cancel(s2);
            flag2--;
        }

        if(flag1 == 0 && flag2 == 0){
            printf("再见\n"); 
            exit(0);
        }


        printf("re,请输入要切换的目标\n");
        scanf("%d",&flag_temp);
        if(flag_temp == 0)
        {
            printf("已切换到re\n");
            sem_post(&mutex_0);
        }
        if(flag_temp == 1)
        {
            printf("已切换到send1\n");
            sem_post(&mutex_1);
        }
        if(flag_temp == 2)
        {
            printf("已切换到send2\n");
            sem_post(&mutex_2);
        }
        //判断通过输入来判断接下来切换到哪个进程

    }
}

void *sender1(void *arg){
    struct msgbuf buf;
    for(int i=1;i;)
    {
        memset(&buf,0,sizeof(buf));

        sem_wait(&mutex_1);
        sem_wait(&Write);
        //send1需要有操作权并且有Write的权利,才能够写入

        printf("send1,请输入要发送的内容\n");
        scanf("%s",buf.mtext);
        buf.mtype=2;
        if(!strncmp(buf.mtext,"exit",4))
        {   
            strcpy(buf.mtext,"end1");
            i=0;
        }
        else
        {
            strcat(buf.mtext,"(s1)");
        }

        int ret = msgsnd(*(int *)arg,&buf,sizeof(buf.mtext),0);
        //发送消息

        if(ret==-1)
        {
            perror("msgsnd error");
            sem_post(&Write);
            exit(1);
        }
        sem_post(&Read);
        sem_post(&Write);

        printf("send1,请输入要切换的目标\n");
        scanf("%d",&flag_temp);
        if(flag_temp == 0)
        {
            printf("已切换到re\n");
            sem_post(&mutex_0);
        }
        if(flag_temp == 1)
        {
            printf("已切换到send1\n");
            sem_post(&mutex_1);
        }
        if(flag_temp == 2)
        {
            printf("已切换到send2\n");
            sem_post(&mutex_2);
        }
    }
}
void *sender2(void *arg){
    struct msgbuf buf;
    for(int i=1;i;)
    {
        memset(&buf,0,sizeof(buf));

        sem_wait(&mutex_2);
        sem_wait(&Write);
        //send1需要有操作权并且有Write的权利,才能够写入

        printf("send2,请输入要发送的内容\n");
        scanf("%s",buf.mtext);
        buf.mtype=2;
        if(!strncmp(buf.mtext,"exit",4))
        {   
            strcpy(buf.mtext,"end2");
            i=0;
        }
        else
        {
            strcat(buf.mtext,"(s2)");
        }

        int ret = msgsnd(*(int *)arg,&buf,sizeof(buf.mtext),0);

        if(ret == -1)
        {
            perror("msgsnd error");
            sem_post(&Write);
            exit(1);
        }
        sem_post(&Read);
        sem_post(&Write);

        printf("send2,请输入要切换的目标\n");
        scanf("%d",&flag_temp);
        if(flag_temp == 0)
        {
            printf("已切换到re\n");
            sem_post(&mutex_0);
        }
        if(flag_temp == 1)
        {
            printf("已切换到send1\n");
            sem_post(&mutex_1);
        }
        if(flag_temp == 2)
        {
            printf("已切换到send2\n");
            sem_post(&mutex_2);
        }
    }
}
int main(){
    int ret,msgid,x;
    sem_init(&Write,0,1);
    sem_init(&Read,0,0);
    sem_init(&mutex_1,0,1);
    sem_init(&mutex_2,0,0);
    sem_init(&mutex_0,0,0);
    //初始使send1具有操作权以及写权限

    key_t key = 100;
    //key值可随意定义

    msgid=msgget(key,IPC_CREAT|0666);
    if(msgid==-1)
    {
        perror("msgid error");
        exit(1);
    }

    ret=pthread_create(&r,NULL,receive,(void *)&msgid); 
    if (ret!=0)
    {
        perror("receiver create error");
        exit(1);
    }

    ret=pthread_create(&s1,NULL,sender1,(void *)&msgid);
    if (ret!=0)
    {
        perror("sender1 create error");
        exit(1);
    }

    ret=pthread_create(&s2,NULL,sender2,(void *)&msgid);
    if (ret!=0)
    {
        perror("sender2 create error");
        exit(1);
    }

    pthread_join(r,NULL);
    pthread_join(s1,NULL);
    pthread_join(s2,NULL);

    msgctl(msgid,IPC_RMID,NULL);
    return 0;   
}
赞(5)
评论 (0)

互动读者

  • เว็บแท่งหวยออนไลน์闲逛

    评论 1 次 | 文章 0 篇

  • slot terbaru闲逛

    评论 1 次 | 文章 0 篇

  • mobil odeme bozum闲逛

    评论 1 次 | 文章 0 篇

  • nmqberxi闲逛

    评论 1 次 | 文章 0 篇

标签云