zoukankan      html  css  js  c++  java
  • OS: 生产者消费者问题(二) ---- 系统V IPC通信-信号量和共享内存

    在上一篇“OS: 生产者消费者问题(多进程+共享内存+信号量)”中提到的方法二: 如果进程之间并没有父子关系,但是协商好了共享存储的 KEY , 那么在每个进程中,就可以通过 KEY 以及 shmget 函数获得共享存储的 I D , 进而通过 shmat 函数获得共享存储的实际地址,最后访问。

    本文采用此种方式进行同步生产者和消费者。

    1、头文件myshm.h: 要用到的定义和说明

    /*
     * myshm.h
     *
     *  Created on: Aug 3, 2013
     *      Author: root
     */
    
    #ifndef MYSHM_H_
    #define MYSHM_H_
    #endif /* MYSHM_H_ */
    
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    #include <sys/shm.h>
    #include <stdio.h>
    #include <string.h>
    #define SHMSZ 256
    
    union semun{
        int val;
        struct semid_ds * buf;
        unsigned short * array;
    };
    
    void init_a_semaphore(int sid, int semnum, int initval){
        union semun semopts;
        semopts.val = initval;
        semctl(sid, semnum, SETVAL, semopts);
    }
    
    int semaphore_P(int sem_id){
        struct sembuf sb;
        sb.sem_num=0;
        sb.sem_op = -1;
        sb.sem_flg = SEM_UNDO;
        if(semop(sem_id, &sb, 1) == -1){
            printf("semaphore_P failed.
    ");
            return 0;
        }
        return 1;
    }
    
    int semaphore_V(int sem_id){
        struct sembuf sb;
        sb.sem_num=0;
        sb.sem_op = 1;
        sb.sem_flg=SEM_UNDO;
        if(semop(sem_id, &sb, 1) == -1){
            printf("semaphore_V failed.
    ");
            return 0;
        }
        return 1;
    }

    2、生产者程序productProcess.c:

    #include "myshm.h"
    
    int main(){
        char * shm, *s;
        int shmid;
        int producer, consumer, i;
        char readbuf[SHMSZ];
    
        if((consumer = semget((key_t)1234, 1, IPC_CREAT|0660)) == -1){
            printf("server consumer semget failed.
    ");
            exit(1);
        }
        init_a_semaphore(consumer, 0, 0);
    
        if((producer = semget((key_t)5678, 1, IPC_CREAT|0660)) == -1){
            printf("server producer semget failed.
    ");
            exit(1);
        }
        ///printf("ftok("consumer", 0) = %d", (key_t)1234);
        //printf("ftok("consumer", 0) = %d", (key_t)5678);
        //printf("ftok("consumer", 0) = %d", ftok("consumer", 0));
        //printf("ftok("producer", 0) = %d", ftok("producer", 0));
        init_a_semaphore(producer, 0, 1);
    
        if((shmid = shmget(ftok("shared",0), SHMSZ, 0666| IPC_CREAT)) == -1){
            printf("server shmget failed.
    ");
            exit(1);
        }
        if((shm = shmat(shmid, (unsigned char*)0, 0)) == -1){
            printf("server shmat failed.
    ");
            exit(1);
        }
    
        for(i=0;;i++){
            printf("Enter text:");
            fgets(readbuf, SHMSZ, stdin);
            semaphore_P(producer);
            printf("process %d enter pv key area", getpid());
            sprintf(shm, "Message %4d from producer %d is "%s"
    ",i, getpid(), readbuf);
            semaphore_V(consumer);
            if(strcmp(readbuf, "end") == 0){
                break;
            }
        }
        return 0;
    }

    3、消费者程序ConsumerProcess.c:

    #include "myshm.h"
    
    int main(){
        char * shm;
        int shmid;
        int producer, consumer, i;
        if((consumer = semget((key_t)1234, 1, IPC_CREAT|0660)) == -1){
            printf("consumer semget failed.
    ");
            exit(1);
        }
        //init_a_semaphore(consumer, 0, 1);
        if((producer = semget((key_t)5678, 1, IPC_CREAT|0660)) == -1){
            printf("producer semget failed.
    ");
            exit(1);
        }
        //init_a_semaphore(producer, 0, 1);
    
        if((shmid = shmget(ftok("shared", 0), SHMSZ, 0666|IPC_CREAT)) == -1){
            printf("shmget failed
    ");
            exit(1);
        }
        if((shm = shmat(shmid, (unsigned char *)0, 0)) == -1){
            printf("shmat failed.
    ");
            exit(1);
        }
    
        for(i=0;;i++){
            printf("Prepare to get Data from memory
    ");
            semaphore_P(consumer);
            printf("enter pv key memory
    ");
            printf("Data received:%s
    ", shm);
    
            sleep(1);
            semaphore_V(producer);
            if(strcmp(shm, "end") == 0){
                break;
            }
        }
    
        semctl(producer, 0, IPC_RMID,0);
        semctl(consumer, 0, IPC_RMID, 0);
    
        return 1;
    }
  • 相关阅读:
    spring aop实现过程之三Spring AOP中Aspect编织的实现
    spring aop实现过程之一代理对象的生成
    数据库常用面试题(SQL Server) (转载)
    回溯法解八后问题
    masmplus增加调试工具
    c++ new关键字 详解
    EMU8086 编译器使用简介
    汇编操作显存
    回溯法简介
    汇编链接时 错误:unresolved external symbol _WinMainCRTStartup
  • 原文地址:https://www.cnblogs.com/wangle1001986/p/3235046.html
Copyright © 2011-2022 走看看