写出三种进程间通信的代码示例

目录

无名管道

共享内存

消息队列


无名管道

#include

int main(int argc, const char *argv[])
{
    //定义进程号变量
    pid_t pid = -1;
    //定义存放管道文件描述符的数组
    int pipefd[2] = {0};
    //创建管道文件
    if(pipe(pipefd) == -1)
    {
        perror("pipe error");
        return -1;
    }

    //创建一个子进程
    pid = fork();
    if(pid > 0)
    {
        //父进程  
        //关闭父进程中管道的读端
        close(pipefd[0]);
        char buf[128] = "";
        while(1)
        {
            //从终端上获取数据放入buf中
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = 0;        //将'\n'换成'\0'
            write(pipefd[1], buf, sizeof(buf));    //将数据写入管道文件中
            if(strcmp(buf, "quit") == 0)
            {
                break;
            }
        }
        //关闭写端
        close(pipefd[1]);
    }else if(pid == 0)
    {
        //子进程
        //子进程关闭管道的写端
        close(pipefd[1]);
        char rbuf[128] = "";
        while(1)
        {
            bzero(rbuf, sizeof(rbuf));    //将数组内容置0
            read(pipefd[0], rbuf, sizeof(rbuf));   //从管道文件中读取数据
            printf("收到父进程消息: %s\n", rbuf);       
            if(strcmp(rbuf, "quit") == 0)
            {
                break;
            }
        }
        //关闭读端
        close(pipefd[0]);
        //退出子进程
        exit(EXIT_SUCCESS);
    }else
    {
        perror("fork error");
        return -1;
    }
    //父进程回收子进程的资源
    wait(NULL);

    return 0;
}

共享内存

发送端

#include

#define PAGE_SIZE 4096


int main(int argc, const char *argv[])
{
    //1、创建一个key值
    key_t key = ftok("/", 't');
    if(key == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key = %#x\n", key);

    //2、通过key值创建共享内存段
    int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
    if(shmid == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n", shmid);

    //3、将共享内存段映射到用户空间
    char *addr = (char *)shmat(shmid, NULL, 0);

    if(addr == (void*)-1 )
    {
        perror("shmat error");
        return -1;
    }

    //4、使用共享内存段
    //char buf[128] = "";
    while(1)
    {
        printf("请输入:");
        fgets(addr, PAGE_SIZE, stdin);     //向共享内存中输入数据
        addr[strlen(addr)-1] = 0;           //将'\n'换成'\0'
        
        //判断退出条件
        if(strcmp(addr, "quit") == 0)
        {
            break;
        }
    }
    
    //5、取消映射
    if(shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }

    return 0;
}

接收端

#include

#define PAGE_SIZE 4096

int main(int argc, const char *argv[])
{
    //1、创建一个key值
    key_t key = ftok("/", 't');
    if(key == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key = %#x\n", key);

    //2、通过key值创建共享内存段
    int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);
    if(shmid == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n", shmid);

    //3、将共享内存段映射到用户空间
    char *addr = (char *)shmat(shmid, NULL, 0);
    if(addr == (void*)-1 )
    {
        perror("shmat error");
        return -1;
    }
    //4、使用共享内存段
    //char buf[128] = "";
    while(1)
    {
        //读取共享内存中的数据
        printf("共享内存中的数据为: %s\n", addr);
                
        //判断退出条件
        if(strcmp(addr, "quit") == 0)
        {
            break;
        }
    }
    
    //5、取消映射
    if(shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }

    //6、删除共享内存
    if(shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("shmctl error");
        return -1;
    }

    return 0;
}

消息队列

发送端

#include

//定义一个发送消息的结构体类型
struct msgbuf
{
    long mtype;         //消息类型
    char mtext[1024];    //消息正文大小
};

//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))

int main(int argc, const char *argv[])
{
    //1、创建key值
    key_t key = ftok("/", 'k');
    if(key == -1)
    {
        perror("key create error");
        return -1;
    }

    //此时key已经创建出来
    printf("key = %#x\n", key);

    //2、创建消息队列
    int msgid = msgget(key, IPC_CREAT|0664);
    if(msgid == -1)
    {
        perror("msgget error");
        return -1;
    }
    printf("msgid = %d\n", msgid);  //输出消息队列id号

    //3、向消息队列中存放数据
    //定义一个消息类型的变量
    struct msgbuf buf;
    while(1)
    {
        //输入消息内容
        printf("请输入您要发送的类型:");
        scanf("%ld", &buf.mtype);
        printf("请输入消息内容:");
        scanf("%s", buf.mtext);

        //将消息放入消息队列中
        msgsnd(msgid, &buf, SIZE, 0);

        //判断退出条件
        if(strcmp(buf.mtext, "quit") == 0)
        {
            break;
        }
    }

    //4、删除消息队列
    if(msgctl(msgid, IPC_RMID, NULL) == -1)
    {
        perror("msgctl error");
        return -1;
    }

    return 0;
}

接收端

#include

//定义一个发送消息的结构体类型
struct msgbuf
{
    long mtype;         //消息类型
    char mtext[1024];    //消息正文大小
};

//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))


int main(int argc, const char *argv[])
{
    //1、创建key值
    key_t key = ftok("/", 'k');
    if(key == -1)
    {
        perror("key create error");
        return -1;
    }

    //2、创建消息队列
    int msgid = msgget(key, IPC_CREAT|0664);
    if(msgid == -1)
    {
        perror("msgget error");
        return -1;
    }

    //3、从消息队列中读取数据
    //定义一个消息类型的变量
    struct msgbuf buf;
    while(1)
    {

        //将消息从消息队列中读取出来
        msgrcv(msgid, &buf, SIZE, 0, 0);
   
        //将读取的消息打印出来
        printf("收到消息:%s\n", buf.mtext);

        //判断退出条件
        if(strcmp(buf.mtext, "quit") == 0)
        {
            break;
        }
    }

    return 0;
}

你可能感兴趣的:(linux)