进程通信实验报告

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 .实验名称 进程通信 |
| 1. 实验目的 (1)理解进程间通信的概念和方法。 (2)掌握常用的Linux进程间通信的方法。 |
| 1. 实验内容 (1)编写C程序,使用Linux中的IPC机制,完成"石头、剪子、布"的游戏。 (2)修改上述程序,使之能够在网络上运行该游戏。 |
| 4. 实验原理或流程图 消息队列的概念: 消息队列是一种进程间通信机制,允许不同进程之间通过发送和接收消息来交换数据。 每个消息队列都有一个唯一的标识符(key),用于区分不同的队列。 消息队列的创建: 使用msgget()系统调用创建消息队列,需要提供键值(key)和权限(perm)。 IPC_CREAT标志用于创建一个新的消息队列,如果队列已存在则返回现有的队列。 0666是权限掩码,表示任何用户都可以读写消息队列。 消息结构: 消息队列中的消息通常包含一个long类型的消息类型(Type)和一个指向消息数据的指针。 在这份代码中,消息数据是自定义的结构体Game,包含轮次(Round)和消息类型(Type)。 发送消息: 使用msgsnd()系统调用向消息队列发送消息。 需要提供消息队列的标识符(msgid)、指向消息结构的指针、消息长度和标志位(0表示不截断消息)。 接收消息: 使用msgrcv()系统调用从消息队列接收消息。 需要提供消息队列的标识符(msgid)、指向消息结构的指针、消息长度、消息类型和标志位(0表示接收第一个消息)。 消息队列的操作: msgctl()系统调用用于控制消息队列,如删除消息队列(IPC_RMID)。 消息队列的删除: 在程序结束时,应该使用msgctl()系统调用删除消息队列,释放系统资源。 消息队列的同步: 消息队列本身不提供同步机制,需要通过其他方式(如信号量、互斥锁)来确保消息的发送和接收顺序。 消息队列的容量: 消息队列有一个最大消息数和每个消息的最大长度限制,这些限制取决于系统配置。 错误处理: 如果msgget()、msgsnd()或msgrcv()调用失败,它们会返回-1,并设置全局变量errno以指示错误类型 |

cpp 复制代码
#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <time.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/ipc.h>

#include <sys/msg.h>

struct Game   //游戏信息

{

    int Round;

    long Type;

};

void result_send(int num)     //发送出拳信息

{

    struct Game game;

    game.Type = 1;

    game.Round = rand() % 3;

    msgsnd(num, &game, sizeof(int), 0);

}

int result_announce(int a, int b)    //出拳结果的判断

{

    if ((a + 1 == b) || (a - 3 == b))

        return -1;    //a胜b

    else if (a == b)

        return 0;    //ab平局

    else

        return 1;    //a负b

}

void writeFile(int *result_list, int len)   //将每盘的结果存入文件

{

    int count_A = 0;

    int count_B = 0;

    int pingju=0;

    FILE *fin;

    if( (fin = fopen( "result.txt", "w" )) == NULL )

        printf( "This file wasn't opened" );



    int i;

    for (i = 0; i < len ; i++)

    {

        switch(result_list[i])

        {

            case -1 :{

                count_A++;

                fprintf(fin, "NO.%d:A win\n", i + 1);

                printf("NO.%d:A win\n", i + 1);

                break;

            }

            case 0 : {

                pingju++;

                fprintf(fin, "NO.%d:end in a draw\n", i + 1);

                printf("NO.%d:end in a draw\n", i + 1);

                break;

            }

            case 1 : {

                count_B++;

                fprintf(fin, "NO.%d:B win\n", i + 1);

                printf("NO.%d:B win\n", i + 1);

                break;

            }

        }

    }



    printf("\nThe final result is A win:%ds \nB win:%ds \nend in a draw %ds\n",count_A,count_B,pingju);

    fprintf(fin, "\nThe final result is A win:%ds \nB win:%ds \nend in a draw %ds\n",count_A,count_B,pingju);

    fclose(fin);

}

int main()

{

    int times;

    int key1 = 1234;

    int key2 = 5678;

    int *result_list;

    pid_t  pid1, pid2; 

    int msgid1,msgid2;

    msgid1 = msgget(key1, IPC_CREAT | 0666); //创建消息队列

    if(msgid1 == -1)

    {

        fprintf(stderr, "failed with error");

        exit(EXIT_FAILURE);

    }

    msgid2 = msgget(key2, IPC_CREAT | 0666); //创建消息队列

    if(msgid2 == -1)

    {

        fprintf(stderr, "failed with error");

        exit(EXIT_FAILURE);

    }

    printf("Game start,please input rounds:");

    scanf("%d", &times);

    result_list=(int*)malloc(times*sizeof(int));

    int i;

    for (i = 0; i < times; i++)

    {

        pid1 = fork();   //创建选手1

        if (pid1 == 0)

        {

            srand((unsigned)time(0) * 3000 ); //以时间为种子

            result_send(msgid1);  //生成选手1的出拳信息并发送到信息队列

            exit(-1);

        }

        pid2 = fork();   //创建选手2

        if (pid2 == 0)

        {

            srand((unsigned)time(NULL)*i ); //以时间为种子

            result_send(msgid2);  //生成选手2的出拳信息并发送到信息队列

            exit(-1);

        }

        if (pid1 < 0 || pid2 < 0)

        {

            fprintf(stderr, "Fork Failed");

            exit(-1);

        }

        else

        {

            wait(NULL);

            wait(NULL);

            struct Game game1;

            struct Game game2;

//printf("wait ok.\n");

      //从消息队列中取得选手1的出拳信息

            msgrcv(msgid1, &game1, sizeof(game1) - sizeof(long), 0, 0);

//printf("rcv1 ok.\n");

       //从消息队列中取得选手2的出拳信息

            msgrcv(msgid2, &game2, sizeof(game2) - sizeof(long), 0, 0);

       //评判出拳结果

//printf("rcv2 ok.\n");

            int j = result_announce(game1.Round, game2.Round);

 //result_list[i] = result_announce(game1.Round, game2.Round);

            result_list[i] = j;

        }

    }

//printf("end ok.\n");

    //将比赛结果写入文件

    writeFile(result_list, times);

    //删除消息队列

    if (msgctl(msgid1, IPC_RMID, 0) == -1)

    {

        fprintf(stderr, "msgctl(IPC_RMID) failed\n");

    }

    if (msgctl(msgid2, IPC_RMID, 0) == -1)

    {

        fprintf(stderr, "msgctl(IPC_RMID) failed\n");

    }

   exit(EXIT_SUCCESS);}
相关推荐
初夏睡觉2 小时前
c++1.3(变量与常量,简单数学运算详解),草稿公放
开发语言·c++
阿拉斯攀登2 小时前
从入门到实战:CMake 与 Android JNI/NDK 开发全解析
android·linux·c++·yolo·cmake
筱璦5 小时前
期货软件开发 - C# 调用 HQChart 指标计算 C++ 动态库
c++·microsoft·c#
不想写代码的星星5 小时前
C++ 内存管理:分区、自定义分配器、常见问题与检测工具
c++
-许平安-6 小时前
MCP项目笔记九(插件 bacio-quote)
c++·笔记·ai·plugin·mcp
沉鱼.446 小时前
第十三届题目
c语言·c++·算法
liulilittle6 小时前
C++ 无锁编程:单停多发送场景高性能方案
服务器·开发语言·c++·高性能·无锁·原子
无限进步_7 小时前
【C++】巧用静态变量与构造函数:一种非常规的求和实现
开发语言·c++·git·算法·leetcode·github·visual studio
小超超爱学习99377 小时前
大数乘法,超级简单模板
开发语言·c++·算法
xyx-3v8 小时前
qt创建新工程
开发语言·c++·qt