进程间通信(IPC)

进程间通信(IPC)

进程间通信,InterProcess Communication。进程间通信的常见方式有:管道、消息队列、共享内存、信号量

共享内存

简介

可实现两个进程访问同一个逻辑内存。共享内存是由IPC为进程创建的一个特殊的地址范围,出现在该进程的地址空间中,其他进程可以将同一段共享内存连接到它们自己的地址空间中。所有进程都可以访问共享内存中的地址。

系统调用接口

#include<sys/tpyes.h>
#include<sys/ipc.h>
#include<sys/shm.h>

/* key: 整数值,不相关的进程可以通过它来访问同一个共享内存,以此键值来获取一个有效的共享内存标识符;
 size: 要申请的共享内存大小,以字节为单位;
 shmflg: 权限位;
 返回值: 创建成功则返回共享内存标识符,失败返回-1;
*/
int shmget(key_t key, size_t size, int shmflg);



/*第一次创建共享时,还不能被程序使用,必须使用shmat函数将其连接到一个进程的地址空间中*/
/* shm_id: shmget返回的共享内存标识符;
   shm_addr: 指定共享内存连接到当前进程中的地址位置,此参数值通常是个空指针,表示让系统来选择共享内存的地址;
   shmflg: 一组表示位,如读写权限等;
   返回值: 调用成功则返回共享内存第一个字节的指针,如果失败则返回-1;
*/
void* shmat(int shm_id, const void* shm_addr, int shmflg);



/*shmdt函数用来将共享内存从当前进程中分离*/
/* shm_addr: shmat返回的地址指针;
   返回值: 成功返回0,失败返回-1;	
*/
int shmdt(const void* shm_addr); 



/* shm_id: shmget返回的共享内存标识符;
   command: 要采取的动作,例如删除共享内存;
   buf: 指向包含内存模式和访问权限的结构;
   返回值:成功返回0,失败返回-1;
*/
int shmctl(int shm_id, int command, struct shmid_ds* buf);

例子

生产者、消费者

需求:消费者创建一个共享内存段,并将其中的内容显示出来;生产者连接到一个已有的共享内存段,并允许我们向其中写入数据

/*  share.h  */
#define TEXT_SZ 2048
struct shared_use_st{	
   int written_by_you;
   char some_text[TEXT_SZ];
};
/*   consumer.cpp    */
//
// Created by renjie on 2020/11/12.
//
#include<unistd.h>
#include <string.h>
#include<iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<memory>
#include<stdio.h>
#include<stdlib.h>
#include"share.h"
using namespace std;
int main(){
    int running=1;
    int shmId=shmget((key_t)1234, sizeof( shared_use_st), 0666|IPC_CREAT);
    if(shmId==-1){
        perror("shmget error");
        exit(EXIT_FAILURE);
    }
    void* shmAddr=shmat(shmId,(void*)0,0);
    if(shmAddr==(void*)-1){
        perror("shmat error");
        exit(EXIT_FAILURE);
    }
    cout<<"consumer";
    cout<<"memory attached at "<<shmAddr;
    shared_use_st* shared_buff=(shared_use_st*)shmAddr;
    shared_buff->written=0;
    while(running){
        if(shared_buff->written){
            cout<<shared_buff->someText<<endl;
            sleep(1);
            shared_buff->written=0;
            if(strcmp(shared_buff->someText,"end")==0){
                running=0;
            }
        }
    }
    if(shmdt(shmAddr)==-1){
        perror("shmdt error");
        exit(EXIT_FAILURE);
    }
    if(shmctl(shmId,IPC_RMID,0)==-1){
        perror("shmctl error");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
/*          producer.cpp       */
//
// Created by renjie on 2020/11/12.
//

#include<unistd.h>
#include <string.h>
#include<iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<memory>
#include<stdio.h>
#include<stdlib.h>
#include"share.h"
using namespace std;
#define  BUFSIZ 2048
int main(){
    int running=1;
    char buffer[BUFSIZ];
    int shmId=shmget((key_t)1234, sizeof( shared_use_st), 0666|IPC_CREAT);
    if(shmId==-1){
        perror("shmget error");
        exit(EXIT_FAILURE);
    }
    void* shmAddr=shmat(shmId,(void*)0,0);
    if(shmAddr==(void*)-1){
        perror("shmat error");
        exit(EXIT_FAILURE);
    }
    shared_use_st* shared_buff=(shared_use_st*)shmAddr;
    while(running){
        while(shared_buff->written==1){
            sleep(1);
            cout<<"waiting for client ..\n";
        }
        printf("enter some text:");
        cin>>buffer;
        //wmemcpy(reinterpret_cast<wchar_t *>(shared_buff->someText), reinterpret_cast<const wchar_t *>(buffer), TEXT_SZ);
        strcpy(shared_buff->someText,buffer);
        shared_buff->written=1;
        if(strcmp(shared_buff->someText,"end") == 0){
            running=0;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值