System V 信号灯
2015-08-31 23:03
302 查看
1.semget函数创建一个信号灯集或访问一个已存在的信号灯集
oflags值是SEM_R和SEM_A常值的组合。也可以与IPC_CREAT或IPC_CREAT|IPC_EXCL组合。
semctl函数对一个信号灯执行各种控制操作。
System V支持下列cmd值:
GETVAL,SETVAL,GETPID,GETNCNT,GETZCNT,GETALL,SETALL,IPC_RMID,IPC_SET,IPC_STAT
对于系统中的每个信号灯集,内核维护一个如下的信息结构:
*) GETVAL 把semval的当前值作为函数返回值返回;
*) SETVAL 把semval的值设置为arg.val;
*) GETPID 返回sempid的当前值
*) GETNCNT 把semncnt的当前值返回
*) GETZCNT 把semzcnt的当前值返回
*) GETALL 把指定信号灯集中的每个成员的semval值返回,调用者必须分配足够容纳所指定信号灯集中所有成员的semval值的一个unsigned short整数数组,然后把arg.array设置成指向这个数组。
*) SETALL 设置所指定信号灯集中每个成员的semval值。这些值通过arg.array数组指定。
*) IPC_RMID 把由semid指定的信号灯集从系统中删除。
*) IPC_SET 设置所指定信号灯集的semid_ds结构中的一下三个成员:sem_perm.uid,sem_perm.gid和sem_perm.mode,这些值由来自arg.buf参数指向的结构中的相映成员。
*) IPC_STAT 返回所指定的信号灯集的当前semid_ds结构。调用者必须首先分配一个semid_ds结构,并把arg.buf设置成指向这个结构。
使用semget打开一个信号灯集合后,对其中的一个或多个信号灯的操作就使用semop函数来执行。
int semop(int semid, struct sembuf *opsptr, size_t nops);
semop函数用来对一个或多个信号灯进行操作。
其中struct sembuf结构为:
nops参数指出由opsptr指向的sembuf结构数组中元素的数目。
[test@localhost] touch info
[test@localhost] ./semcreat -e info 3
[test@localhost] ./semsetvalues info 1 2 3
[test@localhost] ./semgetvalues info
semval[0] = 1
semval[1] = 2
semval[2] = 3
[test@localhost] ./semops -u info -1 -2 -3 # 给每个操作指定SEM_UNDO标志
[test@localhost] ./semgetvalues info
semval[0] = 1 # 当semops终止时,所有变动都取消
semval[1] = 2
semval[2] = 3
[test@localhost] ./semops info -1 -2 -3 # 不指定SEM_UNDO标志
[test@localhost] ./semgetvalues info
semval[0] = 0 # 变动未被取消
semval[1] = 0
semval[2] = 0
#include <sys/sem.h> int semget(key_t key, int nsems, int oflags);返回一个信号灯的标识符。nsems指定集合中的信号灯数,如果只是打开一个已存在的集合,则该参数指定为0.创建完一个信号灯集,就不能改变其中的信号灯数。
oflags值是SEM_R和SEM_A常值的组合。也可以与IPC_CREAT或IPC_CREAT|IPC_EXCL组合。
semctl函数对一个信号灯执行各种控制操作。
int semctl(int semid, int semnum, int cmd, ...);semid标识待控制其操作的信号灯集,semnum标识该信号灯集中的第semnum个(从0开始)成员,semnum值仅仅用于GETVAL、SETVAL、GETNCNT、GETZCNT和GETPID命令。
System V支持下列cmd值:
GETVAL,SETVAL,GETPID,GETNCNT,GETZCNT,GETALL,SETALL,IPC_RMID,IPC_SET,IPC_STAT
对于系统中的每个信号灯集,内核维护一个如下的信息结构:
struct semid_ds { struct ipc_perm sem_perm; // operation permission struct sem *sem_base; // ptr to array of semaphores in set unsigned short sem_nsems; // number of semaphres in set time_t sem_otime; // time of last semop() time_t sem_ctime; // time of creation or last IPC_SET };其中,struct sem结构如下:
struct sem { unsigned short semval; // semaphore value, nonnective short sempid; // pid of last seccessful semop(), // SETVAL,SETALL unsigned short semncnt; // awaiting semval > current value unsigned short semzcnt; // awaiting semval = 0 };
*) GETVAL 把semval的当前值作为函数返回值返回;
*) SETVAL 把semval的值设置为arg.val;
*) GETPID 返回sempid的当前值
*) GETNCNT 把semncnt的当前值返回
*) GETZCNT 把semzcnt的当前值返回
*) GETALL 把指定信号灯集中的每个成员的semval值返回,调用者必须分配足够容纳所指定信号灯集中所有成员的semval值的一个unsigned short整数数组,然后把arg.array设置成指向这个数组。
*) SETALL 设置所指定信号灯集中每个成员的semval值。这些值通过arg.array数组指定。
*) IPC_RMID 把由semid指定的信号灯集从系统中删除。
*) IPC_SET 设置所指定信号灯集的semid_ds结构中的一下三个成员:sem_perm.uid,sem_perm.gid和sem_perm.mode,这些值由来自arg.buf参数指向的结构中的相映成员。
*) IPC_STAT 返回所指定的信号灯集的当前semid_ds结构。调用者必须首先分配一个semid_ds结构,并把arg.buf设置成指向这个结构。
使用semget打开一个信号灯集合后,对其中的一个或多个信号灯的操作就使用semop函数来执行。
int semop(int semid, struct sembuf *opsptr, size_t nops);
semop函数用来对一个或多个信号灯进行操作。
其中struct sembuf结构为:
struct sembuf { short sem_num; // semaphores number short sem_op; // semaphores operations short sem_flg; // operation flags: 0, IPC_NOWAIT, SEM_UNDO };
nops参数指出由opsptr指向的sembuf结构数组中元素的数目。
// semcreat.c #include <sys/types.h> #include <sys/sem.h> #include <stdlib.h> #include <unistd.h> #define SVSEM_MODE 0644 int main(int argc, char **argv) { int c, oflag, semid, nsems; oflag = SVSEM_MODE | IPC_CREAT; while((c = getopt(argc, argv, "e")) != -1) { switch(c) { case 'e': oflag |= IPC_EXCL; break; } } if(optind != argc - 2) { perror("usage: semcreat [-e] <pathname> <nsems>"); exit(0); } nsems = atoi(argv[optind + 1]); semid = semget(ftok(argv[optind], 0), nsems, oflag); return 0; } // semgetvalues.c #include <sys/ipc.h> #include <sys/sem.h> #include <stdlib.h> #include <stdio.h> union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main(int argc, char **argv) { int semid, nsems, i; struct semid_ds seminfo; unsigned short *ptr; union semun arg; if(argc != 2) { perror("usage: semgetvalues <pathname>"); exit(0); } semid = semget(ftok(argv[1], 0), 0, 0); arg.buf = &seminfo; semctl(semid, 0, IPC_STAT, arg); nsems = arg.buf->sem_nsems; ptr = calloc(nsems, sizeof(unsigned short)); arg.array = ptr; semctl(semid, 0, GETALL, arg); for(i = 0; i < nsems; i++) printf("semval[%d] = %d\n", i, ptr[i]); return 0; } // semops.c #include <stdio.h> #include <sys/types.h> #include <sys/sem.h> #include <sys/ipc.h> #include <stdlib.h> #include <unistd.h> union semun { int va; struct semid_ds *buf; unsigned short *array; }; int main(int argc, char **argv) { int c, i, flag, semid, nops; struct sembuf *ptr; flag = 0; while((c = getopt(argc, argv, "nu")) != -1) { switch(c) { case 'n': flag |= IPC_NOWAIT; break; case 'u': flag |= SEM_UNDO; break; } } if(argc - optind < 2) { perror("usage: semops [-n] [-u] <pathname> operation ..."); exit(0); } semid = semget(ftok(argv[optind], 0), 0, 0); optind++; nops = argc - optind; ptr = calloc(nops, sizeof(struct sembuf)); for(i = 0; i < nops; i++) { ptr[i].sem_num = i; ptr[i].sem_op = atoi(argv[optind + i]); ptr[i].sem_flg = flag; } semop(semid, ptr, nops); return 0; } // semid.c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdlib.h> int main(int argc, char **argv) { int semid; if(argc != 2) { perror("usage: semid <pathname>"); exit(0); } semid = semget(ftok(argv[1], 0), 0, 0); semctl(semid, 0, IPC_RMID); exit(0); } // semsetvalues.c #include <sys/types.h> #include <sys/ipc.h> #include <stdlib.h> #include <sys/sem.h> union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main(int argc, char **argv) { int semid, nsems, i; struct semid_ds seminfo; unsigned short *ptr; union semun arg; if(argc < 2) { perror("usage: semsetvalues <pathname> [values ...]"); exit(0); } semid = semget(ftok(argv[1], 0), 0, 0); arg.buf = &seminfo; semctl(semid, 0, IPC_STAT, arg); nsems = arg.buf->sem_nsems; if(argc != nsems + 2) { perror("%d semaphores in set, %d values specified", nsems, argc - 2); exit(0); } ptr = calloc(nsems, sizeof(unsigned short)); arg.array = ptr; for(i = 0; i < nsems; i++) ptr[i] = atoi(argv[i + 2]); semctl(semid, 0, SETALL, arg); return 0; }
[test@localhost] touch info
[test@localhost] ./semcreat -e info 3
[test@localhost] ./semsetvalues info 1 2 3
[test@localhost] ./semgetvalues info
semval[0] = 1
semval[1] = 2
semval[2] = 3
[test@localhost] ./semops -u info -1 -2 -3 # 给每个操作指定SEM_UNDO标志
[test@localhost] ./semgetvalues info
semval[0] = 1 # 当semops终止时,所有变动都取消
semval[1] = 2
semval[2] = 3
[test@localhost] ./semops info -1 -2 -3 # 不指定SEM_UNDO标志
[test@localhost] ./semgetvalues info
semval[0] = 0 # 变动未被取消
semval[1] = 0
semval[2] = 0
相关文章推荐
- ld: library not found for -lAFNetworking clang: error: linker command failed with exit code 1 (use -
- 延迟操作
- Struts的一些总结
- 在Linux运行期间升级Linux系统(Uboot+kernel+Rootfs)
- 工作杂谈
- HTML
- 【转】Java 集合系列目录(Category)
- 寻找最小k个数或者寻找第K大的数字
- Android发送邮件
- 瞎搞
- Apache之——配置虚拟目录(监听多个端口)
- 软工视频总结(1)-----前五讲回顾
- eMMC分区详解
- 【详解】嵌入式开发中固件的烧录方式
- JavaScript我学之八善变的this---函数执行上下文
- 文化:要么牛逼,要么滚蛋(美团)
- uva 1438 - Asteroids(几何重心+凸包)
- DISTINCT选取多个字段,只DISTINCT一个字段的解决办法
- 2.1.2、构建一个基础镜像
- Android获取当前电量信息(BroadcastReceiver的使用)