LinuxC application development study notes (14) - pipeline algorithm and inter-process communication

Pipeline Algorithms and Interprocess Communication

Implementation of the pipeline

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define  BUFSIZE 1024 

int main()
{
    
    
       
    
    int pd[2],len = 0;
    __pid_t  pid;
    char buf[BUFSIZE];

    if(pipe(pd)<0)
    {
    
    
       
    
        perror("pipe()");
        exit(1);
    }

    pid = fork();
    if (pid<0)
    {
    
    
       
    
        perror("fork()");
        exit(1);
    }
    if (pid == 0)   //child read
    {
    
    
       
    
        close(pd[1]);//关闭写端
        len = read(pd[0],buf,BUFSIZE);
        write(1,buf,len);
        close(pd[0]);
        exit(0);
    }
    else            //parent write
    {
    
    
       
    
        close(pd[0]);
        write(pd[1],"Hello!",6);
        close(pd[1]);
        wait(NULL);
        exit(0);
    }
    


    exit(0);
}

Inter-process communication
1 machine
1, pipeline

内核提供,单工通信,自同步机制,

Anonymous pipe
int pipe(int pipefd[2]);//The 0 end is used as the read port, and the 1 end is used as the write port

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define  BUFSIZE 1024 

int main()
{
    
    
       
    
    int pd[2],len = 0;
    __pid_t  pid;
    int fd;
    char buf[BUFSIZE];

    if(pipe(pd)<0)
    {
    
    
       
    
        perror("pipe()");
        exit(1);
    }

    pid = fork();
    if (pid<0)
    {
    
    
       
    
        perror("fork()");
        exit(1);
    }
    if (pid == 0)   //child read
    {
    
    
       
    
        close(pd[1]);//关闭写端
        dup2(pd[0],0);
        close(pd[0]);
        fd = open("/dev/null",O_RDWR);
        dup2(fd,1);
        dup2(fd,2);
        execl("/usr/local/bin/mpg123","mpg123","-",NULL);
        perror("execl()");
        exit(1);
    }
    else            //parent write
    {
    
    
       
    
        close(pd[0]);   //关闭读端
        //父进程从网上收取数据往管道当中写
        close(pd[1]);
        wait(NULL);
        exit(0);
    }
    


    exit(0);
}

named pipe

mkfifo
2、XSI -> SysV
IPC -> Inter-Process Communication

Active end: The party that sends the packet first.
Passive end: The party that receives the package first (running first, waiting to receive).

key: ftok (so that both parties get the same key value)

Message queue
msgget(); msgsnd, msgrcv
msgop();
msgctl();

Implementation of message queue

protocol proto.h
#ifndef PROTO_H__
#define PROTO_H__

#define KEYPATH "/etc/services"
#define KEYPROJ 'g'
#define NAMESIZE 1024

struct msg_st
{
    
    
       
    
    long mtype;
    char name[NAMESIZE];
    int math;
    int chinese;
};

#endif // !PROTO_H__

receiver code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "proto.h"

int main()
{
    
    
       
    

    key_t key;
    int msgid;
    struct msg_st rbuf;

    key = ftok(KEYPATH,KEYPROJ);
    if (key<0)
    {
    
    
       
    
        perror("ftok()");
        exit(1);
    }
    
    //创建一个msg
    msgid = msgget(key,IPC_CREAT|0600);
    if (msgid < 0)
    {
    
    
       
    
        perror("msgget()");
        exit(1);
    }
    
    while (1)
    {
    
    
       
    
        //接收 打印 接受 打印
        if (msgrcv(msgid,&rbuf,sizeof(rbuf)-sizeof(long),0,0)<0)
        {
    
    
       
    
            perror("msgrcv()");
            exit(1);
        }
        printf("NAME = %s\n",rbuf.name);
        printf("MATH = %d\n ",rbuf.math);
        printf("CHINESE = %d\n ",rbuf.chinese);
        
    }


    msgctl(msgid,IPC_RMID,NULL); 

    exit(0);
}

sender code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include "proto.h"

int main()
{
    
    
       
    
    key_t key;
    struct msg_st sbuf;

    int msgid;

    key = ftok(KEYPATH,KEYPROJ);
    if (key < 0)
    {
    
    
       
    
        perror("ftok()");
        exit(1);
    }
    

    msgid = msgget(key,0);
    if (msgid < 0)
    {
    
    
       
    
        perror("msgget()");
        exit(1);
    }

    sbuf.mtype = 1;
    strcpy(sbuf.name,"xiaohong");
    sbuf.math = rand()%100;
    sbuf.chinese = rand()%100;
    if(msgsnd(msgid,&sbuf,sizeof(sbuf)- sizeof(long),0)<0)
    {
    
    
       
    
        perror("msgsnd()");
        exit(1);
    }

    puts("OK!");

    exit(0);
}

Semaphore array
semget();
semop();
stmctl();

Shared memory
shmget();
shmop();
shmctl();

Implementation of shared memory

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>

#define MEMSIZE 1024 

int main()
{
    
    
       
    
    pid_t pid;

    char *ptr;

    int shmid;
    //没有亲缘关系 使用ftok


    shmid = shmget(IPC_PRIVATE,MEMSIZE,0600);
    if (shmid < 0)
    {
    
    
       
    
        perror("shmget()");
        exit(1);
    }
    

    pid =fork();
    if(pid<0)
    {
    
    
       
    
        perror("fork()");
        exit(1);
    }
    if (pid == 0)   //child write
    {
    
    
       
    
        //映射内存地址
        ptr = shmat(shmid,NULL,0);
        if (ptr == (void*)-1)
        {
    
    
       
    
            perror("shmat()");
            exit(1);
        }
        strcpy(ptr,"hello!\n");
        shmdt(ptr);
        exit(0); 
    }
    else            //parent read
    {
    
    
       
    
        wait(NULL);
        ptr = shmat(shmid,NULL,0);
        if (ptr == (void*)-1)
        {
    
    
       
    
            perror("shmat()");
            exit(1);
        }
        puts(ptr);
        //解除映射
        shmdt(ptr);
        shmctl(shmid,IPC_RMID,NULL);
        exit(0); 
    }

    exit(0);
}

Summary: Shared memory uses 1, I\O storage mapping 2, shm function.
Steps: 1. Create an instance ()
ftok uses: Whether the two communicating parties have kinship, there is kinship, no key value is required, and anonymous IPC_PRIVATE is used directly.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324109472&siteId=291194637