linux实现共享内存同步的四种方法一

本文主要对实现共享内存同步的四种方法进行了介绍。

共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。它是IPC对象的一种。

为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。

同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情。由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等 。

信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。信号灯包括posix有名信号灯、 posix基于内存的信号灯(无名信号灯)和System V信号灯(IPC对象)

方法一、利用POSIX有名信号灯实现共享内存的同步

有名信号量既可用于线程间的同步,又可用于进程间的同步。

两个进程,对同一个共享内存读写,可利用有名信号量来进行同步。一个进程写,另一个进程读,利用两个有名信号量semr, semw。semr信号量控制能否读,初始化为0。 semw信号量控制能否写,初始为1。

读共享内存的程序示例代码如下

semr = sem_open("mysem_r", O_CREAT | O_RDWR , 0666, 0);
        if (semr == SEM_FAILED)
        {
                printf("errno=%d\n", errno);
                return -1;
        }

        semw = sem_open("mysem_w", O_CREAT | O_RDWR, 0666, 1);
        if (semw == SEM_FAILED)
        {
                printf("errno=%d\n", errno);
                return -1;
        }

        if ((shmid = shmget(key, MAXSIZE, 0666 | IPC_CREAT)) == -1)
        {
                perror("semget");
                exit(-1);
        }

        if ((shmadd = (char *)shmat(shmid, NULL, 0)) == (char *)(-1))
        {
                perror("shmat");
                exit(-1);
        }

        while (1)
        {
                em_wait(semr);
                printf("%s\n", shmadd);
                sem_post(semw); 
        }

写共享内存的程序示例代码如下

。。。。。。
        //同读的程序
        while (1)
        {
                sem_wait(semw);
                printf(">");
                fgets(shmadd, MAXSIZE, stdin);
                sem_post(semr); 
        }

方法二、利用POSIX无名信号灯实现共享内存的同步

POSIX无名信号量是基于内存的信号量,可以用于线程间同步也可以用于进程间同步。若实现进程间同步,需要在共享内存中来创建无名信号量。

因此,共享内存需要定义以下的结构体。

typedef struct
        {
                sem_t semr;
                sem_t semw;
                char buf[MAXSIZE];
        }SHM;

读、写程序流程如下图所示。

方法三、利用System V的信号灯实现共享内存的同步

System V的信号灯是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。而Posix信号灯指的是单个计数信号灯

System V 信号灯由内核维护,主要函数semget,semop,semctl 。

一个进程写,另一个进程读,信号灯集中有两个信号灯,下标0代表能否读,初始化为0。 下标1代表能否写,初始为1。

程序流程如下:

写的流程和前边的类似。

方法四、利用信号实现共享内存的同步

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。利用信号也可以实现共享内存的同步。

思路:

reader和writer通过信号通信必须获取对方的进程号,可利用共享内存保存双方的进程号。

reader和writer运行的顺序不确定,可约定先运行的进程创建共享内存并初始化。

利用pause, kill, signal等函数可以实现该程序(流程和前边类似)。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值