Pipeline and message queue for interprocess communication

Keywords: less

Pipeline and message queue for interprocess communication

The Conduit

Basic knowledge

  • The Conduit

    Like real water pipes, water is like data.
    Pipeline is a half-duplex communication mode
    Data can only flow in one direction, and can only be used between processes with common ancestors.

Introduction to Functions

  • int pipe(int fd[2])
    Function: Create Pipeline
    Parameter fd correlation:
    One reader: fd[0]
    A Writer End: fd[1]
    Header file <unistd.h>

  • int read(int fd, void *buf, int count);

    Function: Read pipeline data from reader specified by parameter fd to buffer buf of count size, and return the actual number of bytes read.
    parameter
    fd: Pipeline Reader
    buf: Buffer to save read data
    count: Number of bytes read

  • int write(int fd, void *buf, int count);

    Function: Remove count bytes from buffer buf to pipeline at the write end specified by parameter fd, and return the number of bytes actually written.
    parameter
    fd: Pipeline Writing End
    buf: Buffer, data to be written to the pipeline
    count: The number of bytes written

Exercise content

1. Parent process creates pipes and two child processes p 1 and p2
 2. Subprocess p1 opens a given file (if not, creates a file), writes data to the file, closes the file, and then writes a message "ok" to the pipeline to inform process p2 that it can read the contents of the file.
3. Subprocess p2 reads messages through a pipeline. If the message is "ok", it opens the file, reads the contents of the file, outputs them to the screen and closes the file.

Implementation code

/*2.Using Pipeline to Realize Interprocess Communication
 Write a program, the parent process creates a pipeline and two child processes p1 and p2
 Subprocess p1 opens a given file (if not, creates a file), writes data to the file, closes the file, and then writes a message "ok" to the pipeline to inform process p2 that it can read the contents of the file.
The sub-process p2 reads the message through the pipeline. If the message is "ok", it opens the file, reads the contents of the file, and outputs it to the channel screen.**/

//Pipeline is a half-duplex communication mode
//Data can only flow in one direction and can only be used between processes with common ancestors.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>   //Header file required by pipeline
#include <string.h>
//# include <mem.h>//memset() function
#include <fcntl.h>
#define BUFFER_SIZE 1024

int write_file()  //Write the content into the document.
{
    int f=open("a.txt",O_WRONLY|O_CREAT,0660);//Open the file for the specified path, if there is no automatic creation
    //f is a file pointer
    if(f==-1) //Failed to open
    {
        printf("open file error !\n");
        return 0;
    }
    char buffer[]="this is a file";//Written into a document
    write(f,buffer,sizeof(buffer));
    //Writer specified to parameter f fetches bytes of specified size from the cache buf into the pipeline
    //Return value is the number of bytes actually written
    close(f);//Close files
    return 1;
}
int read_file(char *buffer)
{
    int f=open("a.txt",O_RDONLY,0660);//Open the file for the specified path, if there is no automatic creation
    if(f==-1)//fail to open file
    {
        printf("open file error !\n");
        return 0;
    }
    int numofchar=read(f,buffer,BUFFER_SIZE); //f stands for reading end
    //I don't know how much valid data there is in the buffer, so read out the contents of the buffer size. 
    //Read pipeline data from the reader specified in parameter f to the buffer buf specified in size
    //Returns the number of bytes actually read
    close(f);
    return numofchar;
}
int main(int argc,char *argv[])
{
    int fd[2];  //Create the read and write end of the pipeline (fd [0] read, FD [1] write)
    if(pipe(fd)<0)//Creating Pipelines
    {
        perror("pipe");//Error output function, showing error 0 when there are no errors
        exit(0);
    }
        char mas[100];
        int n;
        memset(mas,0,sizeof(mas)); //Clear buf content to 0
        //Setting a byte to a specified value
    //build son
    pid_t p1;
    p1=fork();
    if(p1<0)  //Failure to create process
    {
        fprintf(stderr,"fork failed");
        exit(-1);
    }
    else if(p1==0)//son
    {
    //Subprocess p1 opens the given file (if not, creates the file)
    //Write data to the file, close the file, and write a message "ok" to the pipeline.“
    //The purpose is to notify process p2 that the file content is readable
        if(write_file())  //Call Write File Function
        {
            close(fd[0]);  //close read
            char *massage = "ok";
            write(fd[1],massage,100); //Write pipeline messages
            //ok is written in fd [1].
        }
    }
    else  //father
    {
        pid_t p2;
        p2=fork();
        if(p2<0)//Failure to create process
        {
            fprintf(stderr,"fork failed");
            exit(-1);
        }
        else if(p2==0)//son
        {
            close(fd[1]); //close write
            read(fd[0],mas,sizeof(mas));// Read the message from the reader
            if(!strcmp(mas,"ok"))  // is "ok" or no
            {
                char data[BUFFER_SIZE];
                int n =read_file(data);  //Read the contents of the file and store them in data
                printf("data of file is : %s. \n",data);//Print out
            }
        }
        else  //father
        {
            exit(0);
        }
    }

    return 0;
}

Message queue

Message queues provide a way to send block data from one process to another.
Each data block is considered to have a type, and the receiving process can receive different types of data blocks independently.

Basic knowledge

  • Message queue

    Link tables for messages, abbreviated as queues
    Identifier: Queue ID
    The structure of messages in the queue:

Introduction to Functions

  • int msgget(key_t key, int flag)
    Header file: <sys/msg.h>
    Function: Open a queue or create a new queue
    Return value: a queue id
    Parameters:
    Key: An identifier, also known as a key. It can be understood as the only port to get the key method:
    Function ftok(const char* path,int id)
    The ftok function generates a key from a path name and item id
    For example: key = ftok(".",'t');
    flag: Control tag, specifying how to create it
    For example: 0660 | IPC_CREAT

  • int msgsnd(int msqid, const void * ptr, size_t nbytes, int flag)

    Header file: <sys/msg.h>
    Function: Write a message to the message queue, that is, send a message.
    Parameters:
    msqid: queue id
    ptr: Structural pointer to the message to be sent, pointing to the address of the message
    nbytes: Number of bytes sent
    Flag: Control flag, generally designated IPC_NOWAIT

  • int msgrcv(int msqid, const void * ptr, size_t nbytes ,long type, int flag) ;

    Header file: <sys/msg.h>
    Function: Read messages from message queues, that is, receive messages.
    Parameters:
    msqid: queue id
    ptr: The received message is saved to the message structure to which the pointer points
    nbytes: Number of bytes received
    type
    == 0 returns the first message of the queue
    > 0 returns the first message of type in the queue
    <0 Returns messages less than or equal to the absolute value of type
    Flag: Control flag, generally designated IPC_NOWAIT

Exercise content

Parent processes create message queues and two child processes p1 and p2
 Subprocess p1 opens a given file (if not, creates a file), writes data to the file, closes the file, and then writes a message "ok" to the message queue to inform process p2 that it can read the contents of the file.
Subprocess p2 reads the message from the message queue. If it receives the message "ok", it opens the file, reads the content of the file, and outputs it to the screen of the channel, closes the file.

Implementation code

/*Parent processes create message queues and two child processes p1 and p2
 Subprocess p1 opens a given file (if not, creates a file), writes data to the file, closes the file, and then writes a message "ok" to the message queue to inform process p2 that it can read the contents of the file.
Subprocess p2 reads the message from the message queue. If it receives the message "ok", it opens the file, reads the content of the file, and outputs it to the screen of the channel, closes the file.
*/
#include<stdio.h>
#include<sys/msg.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
#define NUM 100
//Message Communication
//Message queues provide a way to send block data from one process to another.
//Each data block is considered to have a type, and the receiving process can receive different types of data blocks independently.
struct mymsg
{
        long mytype;  //Storage message type
        char mytext[NUM];//Store message content
};

int main()
{
        FILE *f;   //field name pointer
        pid_t p1,p2;// Two processes
        key_t key; 
        key = ftok(".", 't');
        //Format Conversion Function of System IPC Key Values
        char s[20];
        int mgsid;
        if((mgsid=msgget(key,IPC_CREAT|0666))==-1)//Open a queue or create a new queue

        {
                printf("creat error\n");
                return -1;
        }

        p1=fork();
        if(p1<0)
        {
        fprintf(stderr,"fork failed");
        exit(-1);
        }
        else if(p1==0)
        {
            printf("p1 pid is:%d\n",getpid());  //p1id
            printf("sending the massage...\n");
            sleep(1);  //This thread hibernates for 1 millisecond
            struct mymsg msg1;
            msg1.mytype=getppid(); //Parent process id
            if((f=fopen("hello.txt","w"))==NULL) //fail to open file
            {
                    printf("the file %s not open\n","hello.txt");
                    return ;
            }
            fputs("hello!",f);//Send a character to a stream 
            fclose(f);
            strcpy(msg1.mytext,"ok");  
            if(msgsnd(mgsid,&msg1,sizeof(msg1.mytext),0)<0)//Write a message to a message queue, that is, send a message.

            {
                    printf("sending error!\n");
                    exit(-1);
            }
            else
            {
                    printf("complete sending !\n");
                    exit(0);
            }

        }
        else
        {
            wait(NULL);
            p2=fork();
            if(p2<0)
            {
                    printf("fork creat error!\n");
                    exit(1);
            }
            else if(p2==0)
            {
                    printf("p2 pid is:%d\n",getpid());
                    printf("Receiving the massage...\n");
                    sleep(1);//This thread hibernates for 1 millisecond
                    struct mymsg msg2;
                    msg2.mytype=getppid();
                    if(msgrcv(mgsid,&msg2,NUM,getppid(),0)<0)//Reading a message from a message queue, that is, receiving a message
                    {
                            printf("receving error!!!\n");
                            exit(1);
                    }
                    else
                    {
                            printf("complete receving \n");

                            if(strcmp("ok",msg2.mytext)==0)
                            {
                                    if((f=fopen("hello.txt","r"))==NULL)
                                    {
                                            printf("the file %s no opend.\n","hello.txt");
                                            return;
                                    }
                                    while((fgets(s,20,f))!=NULL)//Read a line or specify a character from a stream
                                    {
                                            printf("the massage is:%s\n",s);
                                    }
                                    fclose(f);
                            }
                    }

                }
                else
                {
                    wait(NULL);
                    exit(0);
                }
        }
        return 0;
}

The content of this blog is introduced here, welcome to correct!

Posted by Delqath on Tue, 02 Jul 2019 12:56:25 -0700