LinuxC应用开发学习笔记(十五)--管道算法和进程间通信

2022/1/13 7:04:06

本文主要是介绍LinuxC应用开发学习笔记(十五)--管道算法和进程间通信,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

管道算法和进程间通信

管道的实现

#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);
}

进程间通信
1台机器
1、管道

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

匿名管道
int pipe(int pipefd[2]);//0端作为读端口,1端作为写端口

#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);
}

命名管道

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

主动端:先发包的一方。
被动端:先收包的一方	(先运行,等待收)。

key:ftok (使得双方拿到同一个key值)

消息队列
msgget();	msgsnd、msgrcv
msgop();
msgctl();

消息队列的实现

协议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__

接收端代码

#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);
}

发送端代码

#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);
}
信号量数组
semget();
semop();
stmctl();

共享内存
shmget();
shmop();
shmctl();

多台机器

3、网络套接字socket



这篇关于LinuxC应用开发学习笔记(十五)--管道算法和进程间通信的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程