1) obtain the semaphore identifier int semget (key_t key, int nsems, int flag)
2) operation semaphore (initialization, deletion, etc.) int semctl (INT Semid, int semnum, int cmd,/* Union semun */)
3) increase or decrease the semaphores. The operation is an atomic operation int semop (INT Semid, struct sembuf semoparray [], size_t NOPs)
SEM. h
#include <sys/shm.h>#include <sys/ipc.h>#include <sys/sem.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define FTOK_FILE "/etc/profile"#define TEST_FILE "/home/root/sem_file.dat"#define STR_LEN 32#define SHM_SIZE 256union semun{ int val; struct semid_ds *buf; unsigned short *array;};typedef struct _tag_shm{ char buf[SHM_SIZE]; unsigned short num;}shm_t;int creat_sem(void){ int semid = 0; key_t key = ftok(FTOK_FILE,11); if(key == -1) { printf("%s: key =-1!\n",__func__); return -1; } semid = semget(key,1,IPC_CREAT|0666); if(semid == -1) { printf("%s: semid =-1!\n",__func__); return -1; } return semid;}int set_semvalue(int semid){ union semun sem_arg; sem_arg.val = 1; if(semctl(semid,0,SETVAL,sem_arg) == -1) { printf("%s: can‘t set value for sem!\n",__func__); return -1; } return 0;}int sem_p(int semid){ struct sembuf sem_arg; sem_arg.sem_num = 0; sem_arg.sem_op = -1; sem_arg.sem_flg = SEM_UNDO; if(semop(semid, &sem_arg,1) == -1) { printf("%s: can‘t do the sem_p!\n",__func__); return -1; } return 0;}int sem_v(int semid){ struct sembuf sem_arg; sem_arg.sem_num = 0; sem_arg.sem_op = 1; sem_arg.sem_flg = SEM_UNDO; if(semop(semid, &sem_arg,1) == -1) { printf("%s: can‘t do the sem_v!\n",__func__); return -1; } return 0;}int del_sem(int semid){ if(semctl(semid,0,IPC_RMID) == -1) { printf("%s : can‘t rm the sem!\n",__func__); return -1; } return 0;}
Read
# Include "SEM. H "int main (void) {int Semid, shmid; char Buf [str_len] = {0}; int I = 0; void * pshm_addr = NULL; shm_t * pshm = NULL; /* obtain the semaphore identifier */Semid = creat_sem (); If (Semid =-1) {printf ("% s: Semid = % d! \ N ", _ FUNC __, Semid); Return-1;}/* after the semaphore is created, the initialization operation */If (set_semvalue (Semid )) {printf ("% s: set_semvalue failed! \ N ",__ func _); Return-1 ;}/ * Get the shared memory identifier */shmid = shmget (ftok (ftok_file, 111), sizeof (shm_t ), ipc_creat | 0666); If (shmid =-1) {printf ("% s: shmid = % d! \ N ",__ func __, shmid); Return-1 ;}/ * The current process connects to the shared memory segment */pshm_addr = shmat (shmid, 0, 0 ); if (pshm_addr = (void *)-1) {printf ("% s: pshm_addr = (void *) 0! \ N ",__ func _); Return-1;} pshm = (shm_t *) pshm_addr; printf (" read process Semid is % d, shmid is % d! \ N ", Semid, shmid);/* Let the Data Writing Process Run first */sleep (4); For (;) {/* occupies the semaphore, P operation */If (sem_p (Semid) {printf ("% s: sem_p failed! \ N ",__ func _); Return-1;} printf (" enter read process! \ N "); printf (" pshm-> num is % d! \ N ", pshm-> num); printf (" pshm-> Buf is % s ", pshm-> BUF); printf (" Leave read process! \ N ");/* release semaphore, V operation */If (sem_v (Semid) {printf (" % s: sem_v failed! \ N ",__ func _); Return-1;} If (! Strncmp (pshm-> Buf, "end", 3) break; sleep (2);}/* Delete semaphores */If (del_sem (Semid )) {printf ("% s: del_sem failed! \ N ", _ FUNC _); Return-1;}/* process and shared memory out */If (shmdt (pshm_addr) =-1) {printf ("% s: shmdt failed! \ N ",__ func _); Return-1;}/* Delete shared memory */If (shmctl (shmid, ipc_rmid, 0) =-1) {printf ("% s: shmctl failed! \ N ",__ func _); Return-1;} printf (" Bye! \ N "); Return 0 ;}
Write
# Include "SEM. H "int main (void) {int Semid, shmid; char Buf [str_len] = {0}; void * pshm_addr = NULL; shm_t * pshm = NULL; int I = 0; /* obtain the semaphore identifier */Semid = creat_sem (); If (Semid =-1) {printf ("% s: Semid = % d! \ N ", _ FUNC __, Semid); Return-1;}/* Get the shared memory identifier */shmid = shmget (ftok (ftok_file, 111 ), sizeof (shm_t), ipc_creat | 0666); If (shmid =-1) {printf ("% s: shmid = % d! \ N ", _ FUNC __, shmid); Return-1;}/* The current process connects to the shared memory segment */pshm_addr = shmat (shmid, 0, 0 ); if (pshm_addr = (void *)-1) {printf ("% s: pshm_addr = (void *)-1! \ N ",__ func _); Return-1;} pshm = (shm_t *) pshm_addr; printf (" read process: Semid is % d, shmid is % d! \ N ", Semid, shmid); For (;) {/* used semaphore, P operation */If (sem_p (Semid) {printf (" % s: sem_p failed! \ N ",__ func _); Return-1;} printf (" Enter write process! \ N "); printf (" enter something, end with end> \ n "); fgets (BUF, str_len, stdin); pshm-> num = I ++; strcpy (pshm-> Buf, Buf); printf ("Leave write process! \ N ");/* release semaphore, V operation */If (sem_v (Semid) {printf (" % s: sem_v failed! \ N ",__ func _); Return-1;} If (! Strncmp (pshm-> Buf, "end", 3) break;}/* process and shared memory out */If (shmdt (pshm_addr) =-1) {printf ("% s: shmdt is failed! \ N ",__ func _); Return-1;} printf (" good bye! \ N "); Return 0 ;}
Shared Memory and semaphores