Tuesday, March 22, 2016

Linux IPC the SEMAPHORE

Ho do the semaphore use?
Semaphore is Linux IPC resources for other process working synchronization.

Linux semaphore set has to create and initialize in first.
Displaying code, Linux IPC semaphore initialize.

seminit.c
#include 
#include 
#include 
#include 
#include 
#include 
 
union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};
 
int main()
{
    key_t key;
    int semid;
    union semun arg;
 
    if ((key = ftok("sem.dat", 'S')) == -1) {
        perror("ftok");
        exit(1);
    }
 
    /* create a semaphore set with 1 semaphore: */
    if ((semid = semget(key, 1, 0666 | IPC_CREAT)) == -1) {
        perror("semget");
        exit(1);
    }
 
    /* initialize semaphore #0 to 1: */
    arg.val = 1;
    if (semctl(semid, 0, SETVAL, arg) == -1) {
        perror("semctl");
        exit(1);
    }
 
    return 0;
}

Semaphore is created via the code you can confirm by command line.
$ ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
0x530120c6 0 hogehoge 666

Semaphore key is made by ftok() file "sem.dat". This file created by command line before running semaphore initialize program.
$touch sem.dat

Next, two processes inter synchronize code.

semproc.c
#include 
#include 
#include 
#include 
#include 
#include 
 
int main(int argc, char** argv) {

    key_t         key;
    int           semID;
    struct sembuf sop;

    sop.sem_num =  0;            // Semaphore number
    sop.sem_op  = -1;            // Semaphore operation is Lock
    sop.sem_flg =  0;            // Operation flag

    // Create key 
    if ((key = ftok("sem.dat", 'S')) == -1) {
        perror("ftok");
        exit(-1);
    }
 
    // Get created semaphore
    if ((semID = semget(key, 1, 0)) == -1) {
        perror("semget");
        exit(-2);
    }
 
    printf("Be going to lock--- -\n");

    // Try to lock semaphore
    if (semop(semID, &sop, 1) == -1) {
        perror("semop()");
        if(errno == EIDRM) {
            printf("errno=EIDRM, ERRNO=%d\n", errno);
            printf("  I'm going to CANCEL this procedure.\n");
            return(1);
        }
        else {
            exit(-3);
        }
    }
    printf("--Locked!\n\n");

    // You are proccesing code.
    printf("Press return --> Unclock, and quit self\n");
    getchar();

    // Try to release semaphore
    sop.sem_op = 1;
    if (semop(semID, &sop, 1) == -1) {
        perror("semop");
        exit(1);
    }
 
    printf("--Unlocked\n");
 
    return 0;
}

Semaphore is made "seminit.c" lock by "semproc" then you are press return-key will unlock semaphore and quit program.
When running "semproc", you run more "semproc" from other terminals. Later running "semproc" are waiting for locking semaphore. Previous running "semproc" quit as soon as next "semproc" take semaphore.

Finally, Used semaphore has to remove when all program end and don't need semaphore.

semrm.c
#include 
#include 
#include 
#include 
#include 
#include 
 
union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};
 
int main()
{
    key_t key;
    int semid;
    union semun arg;
 
    if ((key = ftok("sem.dat", 'S')) == -1) {
        perror("ftok");
        exit(1);
    }
 
    /* grab the semaphore set created by seminit */
    if ((semid = semget(key, 1, 0)) == -1) {
        perror("semget");
        exit(1);
    }
 
    /* remove */
    arg.val = 1;
    if (semctl(semid, 0, IPC_RMID, arg) == -1) {
        perror("semctl");
        exit(1);
    }
 
    return 0;
}
You can confirm removing semaphore via command line.
$ ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
$

No comments:

Post a Comment