linux进程间通信之共享内存

1.概述
共享内存是最快的进程间通信方式,系统在内存中维护一个特殊大小的内存块,进程可以将这快内存使用自己的页表映射到自己的内存空间中,则该内存就可以被两个进程访问实现了通信的功能.而且建立映射关系后传输数据时不用再进入内核,相比于消息队列而言更快.
2.基本数据结构

struct shmid_ds {
struct ipc_perm
shm_perm;
/* operation perms */
int
shm_segsz;
/* size of segment (bytes) */
__kernel_time_t
shm_atime;
/* last attach time */
__kernel_time_t
shm_dtime;
/* last detach time */
__kernel_time_t
shm_ctime;
/* last change time */
__kernel_ipc_pid_t
shm_cpid;
/* pid of creator */
__kernel_ipc_pid_t
shm_lpid;
/* pid of last operator */
unsigned short
shm_nattch;
/* no. of current attaches */
unsigned short
shm_unused;
/* compatibility */
void
*shm_unused2; /* ditto - used by DIPC */
void
*shm_unused3; /* unused */
};

该结构体是内核关于共享内存的抽象,其中shm_segsz表示该内存块的大小.
3.API
int shmget ( key_t key, int size, int shmflg);
打开一个共享内存块,size大小.
void* shmat ( int shmid, char *shmaddr, int shmflg);
将一个共享内存块链接到当前进程的地址空间中.返回下面可以进行数据操纵的指针.
int shmdt ( char *shmaddr );
卸载共享内存

int shmctl ( int shmqid, int cmd, struct shmid_ds *buf );
对共享内存进行管理,如获取权限值,修改结构体shmid等,删除共享内存等.

4

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>

int main(){
    key_t key;
    int value;
    int running = 1;
    int semid;
    void* sharem = NULL;
    key =ftok(".",1);
    semid = semget(key,1,IPC_CREAT | 0660);
    if(semid == -1){
        perror("semget");
        exit(0);
    }
    printf("semid is %d\n",semid);
    if(semctl(semid,0,SETVAL,0) == -1){
        perror("semctl");
        exit(0);
    }
    int shmid;
    shmid = shmget(key,(size_t)2048,IPC_CREAT |0660);
    if(shmid == -1){
        perror("shmid");
        exit(0);
    }
    printf("shmid is %d\n",shmid);
    sharem = shmat(shmid,NULL,0);
    if(sharem == NULL){
        perror("shmat");
        exit(0);
    }
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_flg = SEM_UNDO;
    while(running){
        if((value = semctl(semid, 0 ,GETVAL)) == 0){
            printf("write data operarte\n");
            printf("pls input something:\n");
            scanf("%s",(char*)sharem);
            sem_b.sem_op = 1;
            if(semop(semid,&sem_b,1) == -1){
                perror("semop");
                exit(0);
            }
            if(strcmp(sharem,"end") == 0)
                running --;
        }

    }
    shmdt(sharem);
    return 0;


}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>

int main(){
    int value;
    int running = 1;
    key_t key;
    int shmid,semid;
    key = ftok(".",1);
    void* sharem = NULL;
    semid = semget(key,1,IPC_CREAT|0660);
    if(semid == -1){
        perror("semid");
        exit(0);
    }
    printf("the semid is%d\n",semid);
    shmid = shmget(key,(size_t)2048,IPC_CREAT|0660);
    if(shmid == -1){
        perror("shmget");
        exit(0);
    }
    printf("the shmid is%d\n",shmid);
    sharem = shmat(shmid,NULL,0);
    if(sharem == NULL){
        perror("shmat");
        exit(0);
    }
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_flg = SEM_UNDO;
    while(running){
        if((value = semctl(semid,0,GETVAL)) == 1){
            printf("read data operate\n");
            printf("recving message is %s\n",(char*)sharem);
            sem_b.sem_op = -1;
            if(semop(semid,&sem_b,1) == -1){
                perror("semop");
                exit(0);
            }
            if(strcmp(sharem,"end") == 0)
                running--;
        }
    }
    shmdt(sharem);
    return 0;
}

共享内存的使用需要配合信号量的使用,来避免两个进程同时读写进程,使用0-1信号量可以实现两个进程的互斥访问.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值