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();

共享内存的实现

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

总结:共享内存使用1、I\O存储映射 2、shm函数。
步骤:1、创建实例()
ftok使用:通信双方是否有亲缘关系,有亲缘关系,不需要key数值,直接使用匿名的IPC_PRIVATE。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值