ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux进程间的通信----->共享内存

2021-11-13 12:02:44  阅读:199  来源: 互联网

标签:共享内存 char 进程 ----- Linux shmid sem include


共享内存:

        顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。(取自博客一位大哥-->Linux进程间通信——使用共享内存_tianmo2010的专栏-CSDN博客)

创建虚拟内存之后返回的地址空间属于用户空间, 不同进程可以将同一物理内存区域映射到各自的用户空间中

 知道共享内存的原理之后,开始代码实现:

**首先创建共享内存:

int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
//1234这个可以随意给 只要是大于0的32位整数就好
//128是共享内存空间大小
//IPC_CREAT是创建共享内存的命令  0600是权限

**第一次创建完共享内存时,它还不能被任何进程访问,shmat()函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。

char *s = (char*)shmat(shmid,NULL,0);
//shmid就是上面shmget之后的返回值int shmid

shmat函数原型:

 如上图所示shmat中第二个参数为空:如果为空的话,由系统选择一个合适的进程地址

 然后shmat中第三个int shmflg置为零是他要是为0   读和写的权限都有的

**然后断开映射 (这块断开映射可有可无,因为进程结束后,自动就断开映射了)

 shmdt(s);
//s是上述共享内存的地址

代码统一起来实现:

进程shma.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>

int main()
{
    int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
    assert(shmid != -1);
    
    char *s = (char*)shmat(shmid,NULL,0);
    
    while(1)
    {
        printf("input : \n");
        char buff[128] = {0};
        fgets(buff,128,stdin);
        
        strcpy(s,buff);//向共享内存s中写入数据
        if(strncmp(buff,"end",3) == 0)
        {
            break;
        }
    }
    shmdt(s);
}

shmb.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>

int main()
{
    int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
    assert(shmid != -1);
    
    char *s = (char*)shmat(shmid,NULL,0);
    
    while(1)
    {   
        if(strncmp(s,"end",3) == 0)
        {
            break;
        }
        printf("read: %s\n",s);
        sleep(1);
    }
    shmdt(s);
}

ok  来看运行结果:在输入端shma.c中输入abc  然后输出端shmb.c就会不停的打出abc  直到shma.c输入end结束输入端  它才会停止打印abc

 那么遇到这种情况该怎么办呢?前面一篇博客我写过 :凡是想让进程依次运行最好的办法就是信号量Linux编程题:信号量同步三进程依次打印若干次ABC_神厨小福贵!的博客-CSDN博客和这个是类似的问题

然后下面进行信号量的同步这两进程:实现原理

下面所使用的sem.c   sem.h这些文件都在:我的另一篇博客中:

Linux编程题:信号量同步三进程依次打印若干次ABC_神厨小福贵!的博客-CSDN博客三个进程依次打印ABC.....思路及大致流程如下:思路取自这位大哥:Linux编程题:创建3个线程分别打印abc,用信号量进行同步_cleverlemon的博客-CSDN博客这位大哥写的是线程,不需要自己封装sem那些初始化函数,pv操作函数以及销毁函数,这篇写的是多进程,麻烦一些,大致思路一毛一样来看代码实现:先来对sem所需的初始化函数,pv操作函数,销毁函数进行封装:sem.h#include <stdio.h>#include <stdl.https://blog.csdn.net/qq_45829112/article/details/121222304  

代码实现:shma.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>
#include "sem.h"

int main()
{
    int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
    assert(shmid != -1);
    
    char *s = (char*)shmat(shmid,NULL,0);
    
    sem_init();
    while(1)
    {
        printf("input : \n");
        char buff[128] = {0};
        fgets(buff,128,stdin);
        
        sem_p(SEM1);        

        strcpy(s,buff);//向共享内存s中写入数据
        
        sem_v(SEM2);

        if(strncmp(buff,"end",3) == 0)
        {
            break;
        }
    }
    shmdt(s);
}

shmb.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>
#include "sem.h"

int main()
{
    int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
    assert(shmid != -1);
    
    char *s = (char*)shmat(shmid,NULL,0);
    
    sem_init();

    while(1)
    {   
        sem_p(SEM2);
        if(strncmp(s,"end",3) == 0)
        {
            break;
        }
        printf("read: %s\n",s);
        sleep(1);
    }
    shmdt(s);
    sem_destroy(); //该程序是最后退出的  由该程序完成信号量的销毁
}

然后进行可执行程序的编译链接:

 看运行结果:

 该程序的难点在于仅仅使用共享内存进行通信的时候,输出输入达不到预期效果(也就是输出端一直打印同一个值),这时候就得想到使用信号量来同步两个进程,来使得两进程可以达到通信的效果!

“能看到这里的亲兄弟们,都是认真上进的亲兄弟,加油!!!”

标签:共享内存,char,进程,-----,Linux,shmid,sem,include
来源: https://blog.csdn.net/qq_45829112/article/details/121300904

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有