IPC-sem 信号量
来源:互联网 发布:手势锁屏软件 编辑:程序博客网 时间:2024/05/16 17:43
int semget(key_t key, int nsems, int semflg); int semop(int semid, struct sembuf *sops, unsigned nsops);The elements of this structure are of type struct sembuf, containing the following members: unsigned short sem_num; /* semaphore number */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */ int semctl(int semid, int semnum, int cmd, ...); union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ };
[root@localhost ch14]# cat semun.h #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) /* union semun is defined by including <sys/sem.h> */#else /* according to X/OPEN we have to define it ourselves */ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ };#endif[root@localhost ch14]# cat sem1.c /* After the #includes, the function prototypes and the global variable, we come to the main function. There the semaphore is created with a call to semget, which returns the semaphore ID. If the program is the first to be called (i.e. it's called with a parameter and argc > 1), a call is made to set_semvalue to initialize the semaphore and op_char is set to X. */#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/sem.h>#include "semun.h"static int set_semvalue(void);static void del_semvalue(void);static int semaphore_p(void);static int semaphore_v(void);static int sem_id;int main(int argc, char *argv[]){ int i; int pause_time; char op_char = 'a'; srand((unsigned int)getpid()); sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT); printf("%d\n",sem_id); if (argc > 1) { if (!set_semvalue()) { fprintf(stderr, "Failed to initialize semaphore\n"); exit(EXIT_FAILURE); } op_char = 'b'; // op_char = argv[1]; sleep(5); }/* Then we have a loop which enters and leaves the critical section ten times. There, we first make a call to semaphore_p which sets the semaphore to wait, as this program is about to enter the critical section. */ for(i = 0; i < 10; i++) { if (!semaphore_p()) exit(EXIT_FAILURE); printf("%c", op_char);fflush(stdout); // pause_time = rand() % 3;pause_time = 1; sleep(pause_time); printf("%c", op_char);fflush(stdout);/* After the critical section, we call semaphore_v, setting the semaphore available, before going through the for loop again after a random wait. After the loop, the call to del_semvalue is made to clean up the code. */ if (!semaphore_v()) exit(EXIT_FAILURE); // pause_time = rand() % 2;pause_time =1; sleep(pause_time); } printf("\n%d - finished\n", getpid()); if (argc > 1) { sleep(10); del_semvalue(); } exit(EXIT_SUCCESS);}/* The function set_semvalue initializes the semaphore using the SETVAL command in a semctl call. We need to do this before we can use the semaphore. */static int set_semvalue(void){ union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0); return(1);}/* The del_semvalue function has almost the same form, except the call to semctl uses the command IPC_RMID to remove the semaphore's ID. */static void del_semvalue(void){ union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) fprintf(stderr, "Failed to delete semaphore\n");}/* semaphore_p changes the semaphore by -1 (waiting). */static int semaphore_p(void){ struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; /* P() */ sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_p failed\n"); return(0); } return(1);}/* semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1, so that the semaphore becomes available. */static int semaphore_v(void){ struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; /* V() */ sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed\n"); return(0); } return(1);}[root@localhost ch14]#
[root@localhost ch14]# ./sem1 9&[2] 7345[root@localhost ch14]# 557056./sem1 557056aaaaaaaabbaabbaabbaabbaabbaabbaab7348 - finishedb[root@localhost ch14]# bbbbbb7345 - finished应该先运行一个带参数的sem1以设置semun.val的初始值,不过它有一个初始值是信号量为不可用状态,
所以先运行一个没有参数的sem1也行,但它在获取信号量的时候,会被阻塞
直到运行了一个带参数的sem1,来设置了semun.val的初始值,信号量变为可用
然后二者竞争信号量
- IPC-sem 信号量
- IPC信号量 sem
- linux SysV IPC sem信号量实现
- IPC实现机制(四)---信号量(sem)
- sem信号量
- sem 信号量
- 信号量sem
- IPC(shm+sem)
- 信号量sem简介
- linux sem信号量使用
- SEM 信号量线程控制
- 关于信号量sem
- Linux sem信号量使用
- 信号量(sem)
- 信号量IPC
- 信号量IPC
- IPC-信号量
- IPC-信号量
- Android手机开发:网络连接-打开Url下载信息
- 桥接、交换和路由三者的区别
- POJ 百练2964: 日历问题
- Ruby学习札记(7)-Ruby中具有循环控制的方法和语句大归纳
- 构造函数析构函数输出顺序
- IPC-sem 信号量
- 基于LIBPCAP的HTTP协议还原与模式匹配
- 秋藕最补人 8款食谱益胃健脾 养血补虚
- 2011暑假总结
- 构建大型jQuery应用
- TCP Performance problems caused by interaction between Nagle's Algorithm and Delayed ACK
- 程序员装B指南
- Android开发之JSON详细总结
- Nagle's algorithm