Linux: 进程间通信

管道

管道式通过调用pipe()函数创建的,若成功返回0,若出错返回-1。

int pipe(int fd[2]);

经由参数fd返回两个文件描述符:fd[0]为而打开,fd[1]为写而打开,fd[1]的输出是fd[0]的输入。
在这里插入图片描述

//创建一个子进程到父进程的管道,子进程经由该管道向父进程传送数据
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( void ) { 
    int fds[2];

    pipe(fds);

    pid_t pid = fork();
    if ( pid == 0 ) { 
        close(fds[0]); // 关闭管道读
        sleep(2);
        write(fds[1], "abc", 3); 
        close(fds[1]);
    } else {
        close(fds[1]);
        char buf[12] = {}; 
        read(fds[0], buf, 12);
        close(fds[0]);
        printf("parent : %s\n" ,buf);
    }   
}
/*------------------------------------
parent : abc
*/

消息队列

消息队列是消息的链接表,存储在内核中有消息对列标识符标识。消息队列是一个跨进程的队列,一个进程将数据放入队列,另一个进程从消息队列中取出数据。

  • ipcs -q 查看消息队列

创建一个消息队列。[注]创建消息队列的进程结束了,消息队列也应该存在。

int msgget(key_t key, int msgflg)
flag:如果是打开消息队列,填写0;如果是创建消息队列IPC_CREATE|0644;

创建消息队列1234

int main( void ) {
    int id = msgget(1234, IPC_CREAT|0644);
    if ( id == -1 ) perror("msgget"),exit(1);
    printf("msgget ok\n");
}

调用msgsnd将消息放入消息队列中。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgp一般为以下结构体
struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

发送消息

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
    long channel;
    char buf[100];
};

int main( void ) { 
    int id = msgget(1234, 0); 

    struct msgbuf mb; 
    printf("channel:");
    scanf("%d", &mb.channel);
    printf("msg:");
    scanf("%s", &mb.buf);
    if ( msgsnd(id, &mb, strlen(mb.buf), 0) == -1 )
      perror("msgsnd"),exit(1);
}
/*----------------------------------------
channel:3
msg:abc
*/

msgrcv从消息队列中取用消息。

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数type可以指定要哪一种消息:
type==0 返回队列中第一个消息
type>0 返回队列中第一个type类型的消息

取用消息

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
    long channel;
    char buf[100];
};

int main( void ) { 
    int id = msgget(1234, 0); 
    struct msgbuf mb; 

    long c;
    memset(&mb, 0x00, sizeof(mb));
    printf("你想读取哪个通道的数据:");
    scanf("%ld", &c);
    msgrcv(id, &mb, 100, c, 0); 
    printf("%s\n", mb.buf);
}
/*------------------------------------------------------
你想读取哪个通道的数据:3
abc
*/

msgctl对队列执行多种操作

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
删除消息队列:msgctl(id, IPC_PMID, NULL);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值