在 Linux 中,进程间通信的另一个机制是信号量。信号量是一种计数器,用于实现并发机制以及防止对共享内存的同时访问。当一个进程访问共享数据时,它可以使用信号量来阻止其他进程访问该数据,直到共享数据被释放。 信号量的创建和操作使用的是semget、semop和semctl等系统调用。 使用示例: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <string.h> #define KEY 0x2023 union semun { int val; /* SETVAL 用,设置信号量的初始值 */ struct semid_ds *buf; /* IPC_STAT 和 IPC_SET 用,访问信号量的参数 */ unsigned short *array; /* GETALL 和 SETALL 用,获取或设置信号量的数组值 */ }; void P(int semid) { struct sembuf buf; buf.sem_num = 0; buf.sem_op = -1; //P : -1 V: 1 buf.sem_flg = SEM_UNDO; if(semop(semid,&buf , 1) == -1) { perror("sem P error"); } } void V(int semid) { struct sembuf buf; buf.sem_num = 0; buf.sem_op = 1; //P : -1 V: 1 buf.sem_flg = SEM_UNDO; if(semop(semid,&buf , 1) == -1) { perror("sem V error"); } } void sem_destory(int semid) { if(semctl(semid,0,IPC_RMID)==-1) perror("destory sem error"); } int main(int argc,char **argv) { int semid = 0 ; int n = 0; int creat_ps = 1; int cnt = 0; //union semun *p = NULL; //union semun a; semid = semget(KEY, 1 , IPC_CREAT | IPC_EXCL | 0666 ); if(semid == -1 ) { semid = semget(KEY, 1 , 0666 ); if(semid == -1) { perror("sem get error"); goto exits; } else { /*p = (union semun *)malloc(sizeof(union semun)); if(p == NULL) { goto exits; } p->val = 1;*/ union semun a; a.val = 1; //if(semctl(semid, 0 , SETVAL , *p ) == -1) if(semctl(semid, 0 , SETVAL , a ) == -1) { perror("sem init error"); goto exits; } creat_ps = 0; } } printf("start run %d\n", creat_ps); while(1) { P(semid); fflush(stdout); if(creat_ps) { printf("AAAAAAAAAAAAAAAAAAA\n"); printf(" 11 \n"); printf(" 11 \n"); printf("AAAAAAAAAAAAAAAAAAA\n"); printf("\n\n"); } else { printf("BBBBBBBBBBBBBBBBBBB\n"); printf(" 22 \n"); printf("BBBBBBBBBBBBBBBBBBB\n"); printf("\n\n"); } V(semid); n = rand()%3; sleep(n); cnt++; if(cnt > 10) break; } exits: if(creat_ps) sem_destory(semid); /*if(p != NULL) { free(p); }*/ return 0; } 执行结果: 开启两个不同进程,进程A wythe@XXXXX:~/linux-sys$ ./sem start run 1 AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA 11 11 AAAAAAAAAAAAAAAAAAA 进程B wythe@xxxxx:~/linux-sys$ ./sem start run 0 BBBBBBBBBBBBBBBBBBB 22 BBBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBBBB 22 BBBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBBBB 22 BBBBBBBBBBBBBBBBBBB BBBBBBBBBBBBBBBBBBB 22 BBBBBBBBBBBBBBBBBBB |
|
来自: wythe > 《Linux系统编程》