信号量:进程A创建共享内存和只有一个信号量的信号量组,且信号量的值为1,进程B和进程C通过信号量实现对共享内存的互斥访问

/**************** 进程A ****************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>


union semun{
    int val;
    struct semid_ds *buf;
    signed short *array;
};

int main(){
    // 1.生成键值key
    key_t key = ftok( "/home/yj/Desktop/fork_test.c", 'A');
    if( -1 == key ){
        fprintf( stderr, "ftok error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 2.创建一个共享内存
    int shmid = shmget( key, 128, IPC_CREAT|0644);
    if( -1 == shmid ){
        fprintf( stderr, "shmget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 3.将物理内存地址映射到进程内
    char *pshm = (char *)shmat( shmid, NULL, 0);
    if( (void *)-1 == pshm ){
        fprintf( stderr, "shmgat error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 4.创建只有一个信号量的信号量组
    int semid = semget( key, 1, IPC_CREAT|0644);
    if( -1 == shmid ){
        fprintf( stderr, "semget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 5.将信号量初值设置为1
    union semun arg;
    arg.val = 1;
    semctl( semid, 0, SETVAL, arg);

    return 0;
}





/**************** 进程B ****************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>




struct sembuf{
    unsigned short sem_num;
    short          sem_op;
    short          sem_flg;
};

int main(){
    int num = 0;

    // 1.生成键值key
    key_t key = ftok( "/home/yj/Desktop/fork_test.c", 'A');
    if( -1 == key ){
        fprintf( stderr, "ftok error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 2.打开目标共享内存
    int shmid = shmget( key, 128, IPC_CREAT|0644);
    if( -1 == shmid ){
        fprintf( stderr, "shmget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 3.将物理内存地址映射到进程内
    char *pshm = (char *)shmat( shmid, NULL, 0);
    if( (void *)-1 == pshm ){
        fprintf( stderr, "shmgat error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 4.打开目标信号量组
    int semid = semget( key, 0, 0644);
    if( -1 == semid ){
        fprintf( stderr, "semget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    bzero( pshm, 128);

    while(1){
        // 5.申请资源
        struct sembuf p = { 0, -1, SEM_UNDO};
        semop( semid, &p, 1);

        // 6.往共享内存里面写入数据
        num = atoi(pshm);
        sprintf( pshm, "%d\n", num+1);
        
        sleep(3);
        // 7.释放资源
        struct sembuf v = { 0, +1, SEM_UNDO};
        semop( semid, &v, 1);
    
    }
    
    return 0;
}





/**************** 进程C ****************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


struct sembuf{
    unsigned short sem_num;
    short          sem_op;
    short          sem_flg;
};

int main(){
    int num = 0;
    // 1.生成键值key
    key_t key = ftok( "/home/yj/Desktop/fork_test.c", 'A');
    if( -1 == key ){
        fprintf( stderr, "ftok error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 2.打开目标共享内存
    int shmid = shmget( key, 128, IPC_CREAT|0644);
    if( -1 == shmid ){
        fprintf( stderr, "shmget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 3.将物理内存地址映射到进程内
    char *pshm = (char *)shmat( shmid, NULL, 0);
    if( (void *)-1 == pshm ){
        fprintf( stderr, "shmgat error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    // 4.打开目标信号量组
    int semid = semget( key, 0, 0644);
    if( -1 == semid ){
        fprintf( stderr, "semget error,errno=%d,%s", errno, strerror(errno));
        return 0;
    }

    while(1){
        // 5.申请资源
        struct sembuf p = { 0, -1, SEM_UNDO};
        semop( semid, &p, 1);

        // 6.往共享内存里面写入数据
        num = atoi(pshm);
        printf("number is %d\n",num);
        
        // 7.释放资源
        struct sembuf v = { 0, +1, SEM_UNDO};
        semop( semid, &v, 1);
        sleep(1);
    }
    
    return 0;
}
posted @ 2026-09-16 17:36    阅读(5)  评论(0)    收藏  举报