一、System V 信號量
1.信號量linux命令
顯示:
ipcs -a 顯示所有共享內核對象
ipcs -s 顯示信號量 s = semphore刪除:
ipcrm -s ID 刪除信號量
?
二、主要函數應用
1. 函數原型:
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);
參數:
- key:信號集的名字
- nsems:信號集中信號量的個數
- semflg:由九個權限標志構成,它們的用法和創建文件時用的mode模式標志是一樣的。
?
2. 函數原型:
#include <sys/sem.h>
int semctl(int semid. int semnum, int cmd, ..../*union semun arg*/);
參數:
- semid:由semget返回的信號集標識碼
- semnum:信號集中信號量的序號
- cmd:將要采取的動作(有三個可能取值)
- 最后一個參數根據命令不同而不同
cmd:
命令 | 說明 |
---|---|
SETVAL | 設置信號量集中信號量的計數值 |
GETVAL | 獲取信號集中的信號量的計數值 |
IPC_STAT | 對此集合取semid_ds結構,并存儲在arg.buf指向的結構中 |
IPC_SET | 在進程有足夠權限的前提下,把信號集中的當前關聯值設置為semid_ds 數據結構中給出的值 |
IPC_RMID | 刪除信號集 |
?
3. 函數原型:
#include <sys/sem.h>
int semop(int semid, struct sembuf semoparray[], size_t nops);
參數:
- semid:是該信號集量的標識碼ID,也是semget函數的返回值。
- sops:是一個指向結構體的指針
- nsops:操作的信號量的個數
?
三、程序清單
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>#define ERR_EXIT(m) do { perror(m), exit(EXIT_FAILURE); }while(0)
union semun
{int val;struct semid_ds *buf;unsigned short *array;
};int sem_creat(key_t key)
{int semid;semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);if (semid == -1)ERR_EXIT("semget");return semid;
}int sem_open(key_t key)
{int semid;semid = semget(key, 0, 0);if (semid == -1)ERR_EXIT("semget");return semid;
}int sem_setval(int semid, int val)
{union semun su;su.val = val;int ret;ret = semctl(semid, 0, SETVAL, su);if (ret == -1)ERR_EXIT("sem_setval");return 0;
}
int sem_getval(int semid)
{int ret;ret = semctl(semid, 0, GETVAL, 0);if (semid == -1)ERR_EXIT("sem_getval");printf("current val is %d\n", ret);return ret;
}int sem_d(int semid)
{int ret;ret = semctl(semid, 0, IPC_RMID, 0);if (ret == -1)ERR_EXIT("semctl");return 0;
}int sem_p(int semid)
{struct sembuf sb = { 0, -1, 0 };int ret;ret = semop(semid, &sb, 1);if (ret == -1)ERR_EXIT("semop"); return ret;
}int sem_v(int semid)
{struct sembuf sb = { 0, 1, 0 };int ret;ret = semop(semid, &sb, 1);if (ret == -1)ERR_EXIT("semop"); return ret;
}int sem_getmode(int semid)
{union semun su;struct semid_ds sem;su.buf = &sem;int ret = semctl(semid, 0, IPC_STAT, su);if (ret == -1)ERR_EXIT("semctl");printf("currcnt pcrmissions id %o\n", su.buf->sem_perm.mode);return ret;
}int sem_setmode(int semid, char *mode)
{union semun su;struct semid_ds sem;su.buf = &sem;int ret = semctl(semid, 0, IPC_STAT, su);if (ret == -1)ERR_EXIT("semctl");printf("cuttent permissions is %o\n", su.buf->sem_perm.mode);sscanf(mode, "%o", (unsigned int*)&su.buf->sem_perm.mode);ret = semctl(semid, 0, IPC_SET, su);if (ret == -1)ERR_EXIT("semctl");printf("permissins updated...\n");
}void usage(void)
{fprintf(stderr, "usage\n");fprintf(stderr, "semtool -c\n");fprintf(stderr, "semtool -d\n");fprintf(stderr, "semtool -p\n");fprintf(stderr, "semtool -v\n");fprintf(stderr, "semtool -s <val>\n");fprintf(stderr, "semtool -q\n");fprintf(stderr, "semtool -f\n");fprintf(stderr, "semtool -m <mode>\n");
}int main(int argc, char *argv[])
{int opt;opt = getopt(argc, argv, "cdpvs:gfm:");if (opt == '?')exit(EXIT_FAILURE);if (opt == -1){usage();exit(EXIT_FAILURE);}key_t key = ftok(".", 's');int semid;switch (opt){case'c':sem_creat(key);break;case'p':semid = sem_open(key);sem_p(semid);sem_getval(semid);break;case'v':semid = sem_open(key);sem_v(semid);sem_getval(semid);break;case'd':semid = sem_open(key);sem_d(semid);break;case's':semid = sem_open(key);sem_setval(semid, atoi(optarg));break;case'g':semid = sem_open(key);sem_getval(semid);break;case'f':semid = sem_open(key);sem_getmode(semid);break;case'm':semid = sem_open(key);sem_setmode(semid, argv[2]);break;}return 0;
}
?
四、參考資料
- getopt函數用法
?