代码示例_IPC_信号量灯

信号量_实现共享内存

 


1.sem.h

#ifndef __SEM_H__
#define __SEM_H__

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


union semun{
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
};


key_t Get_Key(void);
int Shm_Creat(key_t key, size_t size);
void *Shm_At(int shmid);
int Shm_Dt(const void *shmaddr);
int Shm_Del(int shmid);


int Sem_Creat(key_t key);
void Sem_Init(int semid, int value);
void Sem_P(int semid);
void Sem_V(int semid);
int Sem_Delet(int semid);



#endif


2.shm.c

#include"sem.h"


//创建获取
int Shm_Creat(key_t key, size_t size)
{
    int shmid =shmget(key, size, 0666|IPC_CREAT);
    if(shmid < 0){
        perror("Shm_Creat shmget failed ");
        exit(1);
    }
    return shmid;
}

//挂载
void *Shm_At(int shmid)
{
    char *shmat_rel =shmat(shmid,NULL,0);
    if(shmat_rel < 0){
        perror("Shm_At shmat failed ");
        exit(1);
    }
    return shmat_rel;
}

//卸载
int Shm_Dt(const void *shmaddr)
{
    int shmdt_rel =shmdt(shmaddr);
    if(shmdt_rel < 0){
        perror("Shm_Dt shmdt failed ");
        exit(1);
    }
    return shmdt_rel;
}

//删除
int Shm_Del(int shmid)
{
    int shmctl_rel =shmctl(shmid, IPC_RMID, NULL);
    if(shmctl_rel < 0){
        perror("Shm_Del shmctl failed ");
        exit(1);
    }
    return shmctl_rel;
}



 3.sem.c

#include "sem.h"


//获取key
key_t Get_Key(void)
{
    key_t key =ftok("/",0x66);
    if(key <0){
        perror("Get_Key ftok failed");
        exit(1);
    }
    return key;
}

//创建获取
int Sem_Creat(key_t key)
{
    int sem_num =1;
    int semid = semget(key, sem_num,IPC_CREAT|0666);
        if(semid<0){
        perror("sem_creat semget failed");
        exit(1);
    }
    return semid;
}

//初始化
void Sem_Init(int semid, int value)
{
    union semun sem;
    sem.val = value;
    if( semctl(semid,0,SETVAL,sem) <0 ){
        perror("sem_init semctl init failed");
        exit(1);
    }
}

//P操作
void Sem_P(int semid)
{
    struct sembuf buf ={0,-1,SEM_UNDO};
    if( semop(semid,&buf,1) <0 ){
        perror("sem_p semop failed");
        exit(1);
    }
}

//V操作
void Sem_V(int semid)
{
    struct sembuf buf ={0,1,SEM_UNDO};
    if( semop(semid,&buf,1) <0 ){
        perror("sem_v semop failed");
        exit(1);
    }
}

//删除
int Sem_Delet(int semid)
{
    union semun sem;
    if( semctl(semid,0,IPC_RMID, sem) <0 ){
        perror("sem_delet semctl failed");
        exit(1);
    }
}

3.sem_c.c

#include "sem.h"


int main(void)
{
    //sem
    key_t key =Get_Key();
    int semid =Sem_Creat(key);
    Sem_Init(semid,0);
    //shm
    int shmid =Shm_Creat(key,1024);    
    char *shmat_add =Shm_At(shmid);    
    while(1){           //to write  P操作
        Sem_V(semid);            
        fgets(shmat_add, 1024, stdin);
        if(strncmp(shmat_add, "quit", 4) ==0)
            break;
    }
    Shm_Dt(shmat_add);
    Shm_Del(shmid);
    Sem_Delet(semid);

    return 0; 
}

4.sem_s.c

#include "sem.h"


int main(void)
{
    //sem
    key_t key =Get_Key();
    int semid =Sem_Creat(key);
    Sem_Init(semid,0);
    //shm
    int shmid =Shm_Creat(key,1024);    
    char *shmat_add =Shm_At(shmid);    
    while(1){           //to read  V操作
        Sem_P(semid);
        fputs(shmat_add, stdout);
        if(strncmp(shmat_add, "quit", 4) ==0)
            break;
    }
    Shm_Dt(shmat_add);
    Shm_Del(shmid);
    Sem_Delet(semid);

    return 0;
} 

测试:


success !

<笔记>


1.注意头文件是否遗漏 !!

2.信号量初始化了一次

3.

Stay hungry, stay foolish 待续。。。
原文地址:https://www.cnblogs.com/panda-w/p/11049402.html