Binary semaphore P/V operations are encapsulated into dynamic/static libraries and tested separately.

Posted by richarro1234 on Wed, 15 May 2019 11:54:58 +0200

P, V operation
PV operation is related to signal processing, P means pass, V means release.
Ftok function, not to understand its role first to say why it is used, shared memory, message queue, semaphore they are three to find an intermediate medium for communication, this medium is many. It's how to distinguish, just like the only ID card to distinguish people. As long as it's unique, it reminds me of the device number and node of the file. It's unique, but it doesn't seem good to use it directly for identification, but it can be used to generate a number. Ftok () is on the stage. The specific form of ftok function is as follows: key_t ftok(const char* pathname,int proj_id);
The parameter name is the specified file name, which must exist and be accessible. id is a subsequence number, which is an 8 bit integer. The key_t value is returned if the function is successfully executed, or - 1. In general UNIX, the index node of the file is usually taken out, and then the value of key_t is obtained by adding a subordinate number before it.
comm.h

#ifndef _COMM_H_
#define _COMM_H_
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#define PATHNAME "."
#define PROJ_ID 0x6666
union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *_buf;
};
int createSemSet(int nums);
int initSem(int semid,int nums,int initVal);
int P(int semid,int who);
int V(int semid,int who);
int destroySemSet(int semid);
#endif

comm.c

#include "comm.h"
static int commSemSet(int nums,int flags){
    key_t _key = ftok(PATHNAME,PROJ_ID);//Set the file path to the current file
    if(_key < 0){
        perror("ftok");
        return -1;
    }
    //Create and access a semaphore set
    int semid = semget(_key,nums,flags);//key: the name of the signal set, nums: the number of semaphores in the signal set, flags: permission flag
    if(semid < 0){
        perror("semget");
        return -2;
    }
    return semid;
}
int createSemSet(int nums){
    return commSemSet(nums,IPC_CREAT|IPC_EXCL|0666);
}
int getSemSet(int nums){
    return commSemSet(nums,IPC_CREAT);
}
int initSem(int semid,int nums,int initVal){
    union semun _un;
    _un.val = initVal;
    //Control signal set
    if(semctl(semid,nums,SETVAL,_un) < 0){//semid: Signal set identification code returned by semget, nums: Sequence number of semaphore set
        //SETVAL: A counter for setting up semaphores in a semaphore set
        perror("semctl");
        return -1;
    }
    return 0;
}
static int commPV(int semid,int who,int op){
    struct sembuf _sf;
    _sf.sem_num = who;//Numbering of semaphores
    _sf.sem_op = op;//The Value of Addition and Subtraction of Signal in One PV Operation
    _sf.sem_flg = 0;
    //Create and access a semaphore set
    if(semop(semid,&_sf,1) < 0){//semid: semaphore identification code, & sf: sembuf structure, 1: number of semaphores
        perror("semop");
        return -1;
    }
    return 0;
}
int P(int semid,int who){
    return commPV(semid,who,-1);
}
int V(int semid,int who){
    return commPV(semid,who,1);
}
int destroySemSet(int semid){
    if(semctl(semid ,0,IPC_RMID)<0){
        perror("semctl");
        return -1;
    }
}

test_sem.c

#include "comm.h"
int main(){
    int semid = createSemSet(1);
    initSem(semid,0,1);
    pid_t id = fork();
    if(id == 0){
        //child
        int _semid = getSemSet(0);
        while(1){
            P(_semid,0);
            printf("A");
            fflush(stdout);
            usleep(123456);
            printf("A ");
            fflush(stdout);
            usleep(321456);
            V(_semid,0);
        }
    }else{//father
        while(1){
            P(semid,0);
            printf("B");
            fflush(stdout);
            usleep(223456);
            printf("B ");
            fflush(stdout);
            usleep(121456);
            V(semid,0);
        }
        wait(NULL);
    }
    destroySemSet(semid);
    return 0;
}

At this time, there is only one monitor and two processes print at the same time. At this time, the display becomes a critical resource, which is protected by binary semaphores.
Specific encapsulation process before the blog has been written, here is not a specific display. We can see that all AB s appear in pairs, there will be no crossover, if the PV phenomenon is removed, there will be a change.


Printed content interacts with each other, and no paired information is printed.

Topics: Unix