信号灯集(信号量数组): 1、实现进程同步的机制
; 2、在一个信号灯集中,可以有很多信号灯; 3、这些信号灯集中的信号灯相互独立
,每个灯的值的改变都不会影响到其他的信号灯; 4、信号灯的值一般设置为二值量
,即0或者1
,其中0代表没有资源
,1代表有资源
; 常用的接口函数: 一、创建一个信号灯集(semget函数):
# include <sys/sem.h> int semget ( key_t key, int nsems, int semflg) ;
# include <sys/sem.h> int semctl ( int semid, int semnum, int cmd, . . . ) ; union semun{ int val; struct semid_ds * buf; } ;
# include <sys/sem.h> int semop ( int semid, struct sembuf * sops, size_t nsops) ;
# ifndef __SEM_H__ # define __SEM_H__ int sem_init ( int nsems) ; int sem_wait_P ( int semid, int sem_num) ; int sem_post_V ( int semid, int sem_num) ; int sem_exit ( int semid) ; # endif
# include <stdio.h> # include <stdlib.h> # include <string.h> # include <sys/types.h> # include <sys/ipc.h> # include <sys/sem.h> # include <sys/shm.h> # include <unistd.h> # include "sem.h" # include <errno.h> union semun { int val; struct semid_ds * buf; } ; int sem_init ( int nsems) { int semid = 0 ; key_t key = ftok ( "/home/linux/work" , 'K' ) ; if ( - 1 == key) { perror ( "ftok error" ) ; exit ( - 1 ) ; } if ( - 1 == ( semid = semget ( key, nsems, IPC_CREAT| IPC_EXCL| 0666 ) ) ) { if ( EEXIST == errno) { if ( - 1 == ( semid = semget ( key, nsems, IPC_CREAT| 0666 ) ) ) { perror ( "semget error" ) ; exit ( - 1 ) ; } return semid; } else { perror ( "semget error" ) ; exit ( - 1 ) ; } } union semun myval = { . val = 1 } ; if ( - 1 == semctl ( semid, 0 , SETVAL, myval) ) { perror ( "semctl error" ) ; exit ( - 1 ) ; } myval. val = 0 ; for ( int i = 1 ; i < nsems; i++ ) { if ( - 1 == semctl ( semid, i, SETVAL, myval) ) { perror ( "semctl error" ) ; exit ( - 1 ) ; } } return semid; } int sem_wait_P ( int semid, int sem_num) { struct sembuf mysem; mysem. sem_num = sem_num; mysem. sem_op = - 1 ; mysem. sem_flg = 0 ; if ( - 1 == semop ( semid, & mysem, 1 ) ) { perror ( "semop error" ) ; exit ( - 1 ) ; } } int sem_post_V ( int semid, int sem_num) { struct sembuf mysem; mysem. sem_num = sem_num; mysem. sem_op = 1 ; mysem. sem_flg = 0 ; if ( - 1 == semop ( semid, & mysem, 1 ) ) { perror ( "semop error" ) ; exit ( - 1 ) ; } } int sem_exit ( int semid) { if ( - 1 == semctl ( semid, 0 , IPC_RMID) ) { perror ( "semctl error" ) ; exit ( - 1 ) ; } }
# include <stdio.h> # include <stdlib.h> # include <string.h> # include <sys/types.h> # include <sys/ipc.h> # include <sys/sem.h> # include <sys/shm.h> # include <unistd.h> # include "sem.h" # include <errno.h> # define PIGE_SIZE 4 * 1024 int main ( int argc, char const * argv[ ] ) { key_t key = ftok ( "/home/linux/work" , 'K' ) ; if ( - 1 == key) { perror ( "ftok error" ) ; exit ( - 1 ) ; } int shmid = shmget ( key, 2 * PIGE_SIZE, IPC_CREAT| 0666 ) ; if ( - 1 == shmid) { perror ( "shmget error" ) ; exit ( - 1 ) ; } char * k_addr = shmat ( shmid, NULL , 0 ) ; if ( ( void * ) - 1 == k_addr) { perror ( "shmat error" ) ; exit ( - 1 ) ; } int semid = sem_init ( 2 ) ; while ( 1 ) { sem_wait_P ( semid, 0 ) ; fgets ( k_addr, 128 , stdin ) ; k_addr[ strlen ( k_addr) - 1 ] = '\0' ; sem_post_V ( semid, 1 ) ; if ( ! strncmp ( k_addr, "exit" , 4 ) ) { break ; } } if ( - 1 == shmdt ( k_addr) ) { perror ( "shmdt error" ) ; exit ( - 1 ) ; } if ( - 1 == shmctl ( shmid, IPC_RMID, NULL ) ) { perror ( "shmctl error" ) ; exit ( - 1 ) ; } sem_exit ( semid) ; return 0 ; }
# include <stdio.h> # include <stdlib.h> # include <string.h> # include <sys/types.h> # include <sys/ipc.h> # include <sys/sem.h> # include <sys/shm.h> # include <unistd.h> # include "sem.h" # include <errno.h> # define PIGE_SIZE 4 * 1024 int main ( int argc, char const * argv[ ] ) { key_t key = ftok ( "/home/linux/work" , 'K' ) ; if ( - 1 == key) { perror ( "ftok error" ) ; exit ( - 1 ) ; } int shmid = shmget ( key, 2 * PIGE_SIZE, IPC_CREAT| 0666 ) ; if ( - 1 == shmid) { perror ( "shmget error" ) ; exit ( - 1 ) ; } char * k_addr = shmat ( shmid, NULL , 0 ) ; if ( ( void * ) - 1 == k_addr) { perror ( "shmat error" ) ; exit ( - 1 ) ; } int semid = sem_init ( 2 ) ; while ( 1 ) { sem_wait_P ( semid, 1 ) ; printf ( "[%s]\n" , k_addr) ; if ( ! strcmp ( k_addr, "exit" ) ) { break ; } sem_post_V ( semid, 0 ) ; } if ( - 1 == shmdt ( k_addr) ) { perror ( "shmdt error" ) ; exit ( - 1 ) ; } if ( - 1 == shmctl ( shmid, IPC_RMID, NULL ) ) { perror ( "shmctl error" ) ; exit ( - 1 ) ; } sem_exit ( semid) ; return 0 ; }
linux@ubuntu: ~ / work/ MSG/ SME$ . / whellohiI Love Chinalinux@ubuntu: ~ / work/ MSG/ SME$ . / r[ hello] [ hi] [ I Love China]