首页 > 系统相关 >操作系统实验——进程通信(FIFO、shared memory)

操作系统实验——进程通信(FIFO、shared memory)

时间:2022-11-02 21:24:50浏览次数:69  
标签:Process pid FIFO int value memory msg shared message

参考原文链接

共享内存

编译指令:

gcc shared_memory.cpp -I/usr/local/include/ -L/usr/local/lib -lrt -o shared_mem

代码:

/**
 * Sample code for sharing memory between processes
 * Two processes will iteratively increase a counter which values stored in a shared memory
 * 
 */

#include <stdio.h>
#include <unistd.h> // for fork()

#include <sys/mman.h> // for shared memory created
#include <sys/stat.h> // for mode constants
#include <fcntl.h> // for O_* constant

#define SHARED_OBJ_NAME "/somename"

// shared data struct
struct message
{
    int pid;
    int counter;
};

bool write_message(int pid, int value)
{
    int shmFd = shm_open(SHARED_OBJ_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(shmFd, sizeof(message));  
    message *msg_ptr = (message*)mmap(NULL, sizeof(message), PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0);
    
    printf("Process %d: Increase the counter.\n", pid);
    msg_ptr->pid = pid;
    msg_ptr->counter = value;

    munmap(msg_ptr, sizeof(message));

    // remember to close to not hit an error of
    // opening too many files
    close(shmFd);

    return true;
}

bool read_message(int curr_pid, int &curr_value)
{
    int shmFd = shm_open(SHARED_OBJ_NAME, O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(shmFd, sizeof(message));
    message *msg_ptr = (message*)mmap(NULL, sizeof(message), PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0);

    if (msg_ptr->pid == curr_pid)
    {
        printf("Process %d: No new msg available.\n", curr_pid);
        return false;
    }
    else
    {
        printf("Process %d: Receive %d from PID %d.\n", curr_pid, msg_ptr->counter, msg_ptr->pid);
        curr_value = msg_ptr->counter;
        munmap(msg_ptr, sizeof(message));
    }

    close(shmFd);

    return true;
}

int main(int argc, char **argv)
{
    printf("Init the initial value.\n");
    write_message(-1, 0);

    // create a child process by calling folk, 
    // it returns a non-zero pid for parent process and 0 for child process created
    pid_t pid = fork();

    //--- PARENT PROCESS
    if (pid != 0)
    {
        for (int i = 0; i < 5; i++)
        {
            int value;
            // only write message if reading sucessfully
            if (read_message(pid, value)) write_message(pid, ++value);
            sleep(0.1);
        }
    }

    //--- CHILD PROCESS
    else
    {
        for (int j = 0; j < 5; j++)
        {
            int value;
            if (read_message(pid, value)) write_message(pid, ++value);
            sleep(0.1);
        }
    }

    printf("=========== End of process %d\n", pid);
    //shm_unlink(SHARED_OBJ_NAME);

    return 0;
}

运行结果:

Init the initial value.
Process -1: Increase the counter.
Process 440735: Receive 0 from PID -1.
Process 440735: Increase the counter.
Process 440735: Receive 2 from PID 0.
Process 440735: Increase the counter.
Process 440735: No new msg available.
Process 440735: No new msg available.
Process 440735: Receive 4 from PID 0.
Process 440735: Increase the counter.
=========== End of process 440735
Init the initial value.
Process -1: Increase the counter.
Process 0: Receive 1 from PID 440735.
Process 0: Increase the counter.
Process 0: Receive 3 from PID 440735.
Process 0: Increase the counter.
Process 0: Receive 5 from PID 440735.
Process 0: Increase the counter.
Process 0: No new msg available.
Process 0: No new msg available.
=========== End of process 0

FIFO

编译指令:

gcc fifo.cpp -I/usr/local/include/ -L/usr/local/lib -lrt -o fifo
/**
 * Example for using named pipe for communicating between processes
 * This demo is for a unidirectional named pipe which transfer data in one direction
 */

#include "csapp.h"

#define NAMED_PIPE "/var/lock/pipename"

// shared data struct
struct message
{
    int pid;
    int counter;
};


int main(int argc, char **argv)
{
    // create the named pipe (fifo) with permission
    int ret = mkfifo(NAMED_PIPE, 0666);
    if (ret < 0)
        printf("Error when creating FIFO. %s\n", strerror(errno));

    // create a child process by calling folk, 
    // it returns a non-zero pid for parent process and 0 for child process created
    pid_t pid = fork();

    //--- the parent process will write to the pipe only
    if (pid != 0)
    {
        int fd = open(NAMED_PIPE, O_WRONLY);
        for (int i = 0; i < 5; i++)
        {
            message msg;
            msg.pid = pid;
            msg.counter = i;
            printf("Process %d: Write %d.\n", pid, i);
            ret = write(fd, &msg, sizeof(msg));
            if (ret < 0)
                printf("Process %d: Error while writing message. %s\n", pid, strerror(errno));
            sleep(0.1);
        }
        close(fd);
    }

    //-- child process will read only
    else
    {
        int fd = open(NAMED_PIPE, O_RDONLY);
        for (int i = 0; i < 5; i++)
        {
            message msg;
            ret = read(fd, &msg, sizeof(msg));
            if (ret < 0)
                printf("Process %d: Error while reading message. %s\n", pid, strerror(errno));
            printf("Process %d: Received value %d from the parent process %d.\n", pid, msg.counter, msg.pid);
            sleep(0.1);
        }
        close(fd);
    }

    unlink(NAMED_PIPE);

    return 0;
}

运行结果:

Process 424351: Write 0.
Process 424351: Write 1.
Process 424351: Write 2.
Process 424351: Write 3.
Process 424351: Write 4.
Process 0: Received value 0 from the parent process 424351.
Process 0: Received value 1 from the parent process 424351.
Process 0: Received value 2 from the parent process 424351.
Process 0: Received value 3 from the parent process 424351.
Process 0: Received value 4 from the parent process 424351.

标签:Process,pid,FIFO,int,value,memory,msg,shared,message
From: https://www.cnblogs.com/coldarra/p/16852479.html

相关文章