三种信号灯
说明
P/V操作
互斥锁、条件变量和信号量之间的差别
10.2 sem_open()、sem_close()、sem_unlink()函数
#include /* For O_* constants */
#include /* For mode constants */
#include
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);
Link with -pthread.
oflag:如果指定了O_CREAT,那参数三和四就是必须的,信号量尚未存在就初始化它
mode:指定权限位
value:指定信号量的初始值
使用sem_open()打开的信号量使用sem_close()关闭,进程结束时会自动执行
Posix信号量至少是随内核持续的,每个信号量有一个引用计数器记录当前的打开次数
,引用计数大于0时,name就能从文件系统中删除,拆除却要等到最后一个sem_close()
10.3 sem_wait()和sem_trywait()等函数
#include
int sem_wait(sem_t *sem);//被中断返回EINTR
int sem_trywait(sem_t *sem);//失败返回EAGAIN
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem, int *sval);
#include "unpipc.h"
int main(int argc, char **argv)
{
int c, flags;
sem_t *sem;
unsigned int value;
flags = O_RDWR | O_CREAT;
value = 1;
while ( (c = Getopt(argc, argv, "ei:")) != -1) {
switch (c) {
case 'e':
flags |= O_EXCL;
break;
case 'i':
value = atoi(optarg);
break;
}
}
if (optind != argc - 1)
err_quit("usage: semcreate [ -e ] [ -i initalvalue ] ");
sem = Sem_open(argv[optind], flags, FILE_MODE, value);
Sem_close(sem);
exit(0);
}
semgetvalue程序
#include "unpipc.h"
int main(int argc, char **argv)
{
sem_t *sem;
int val;
if (argc != 2)
err_quit("usage: semgetvalue ");
sem = Sem_open(argv[1], 0);
Sem_getvalue(sem, &val);
printf("value = %d\n", val);
exit(0);
}
semwait程序
#include "unpipc.h"
int main(int argc, char **argv)
{
sem_t *sem;
int val;
if (argc != 2)
err_quit("usage: semwait ");
sem = Sem_open(argv[1], 0);
Sem_wait(sem);
Sem_getvalue(sem, &val);
printf("pid %ld has semaphore, value = %d\n", (long) getpid(), val);
pause(); /* blocks until killed */
exit(0);
}
sempost程序
#include "unpipc.h"
int main(int argc, char **argv)
{
sem_t *sem;
int val;
if (argc != 2)
err_quit("usage: sempost ");
sem = Sem_open(argv[1], 0);
Sem_post(sem);
Sem_getvalue(sem, &val);
printf("value = %d\n", val);
exit(0);
}
1.接口
#include
int sem_init(sem_t *sem,int shared,unsigned value);
int sem_destroy(sem_t *sem); //出错返回-1
#include "unpipc.h"
#define NBUFF 10
int nitems; /* read-only by producer and consumer */
struct { /* data shared by producer and consumer */
int buff[NBUFF];
sem_t mutex, nempty, nstored; /* semaphores, not pointers */
} shared;
void *produce(void *), *consume(void *);
int main(int argc, char **argv)
{
pthread_t tid_produce, tid_consume;
if (argc != 2)
err_quit("usage: prodcons2 <#items>");
nitems = atoi(argv[1]);
/* 4initialize three semaphores */
Sem_init(&shared.mutex, 0, 1);
Sem_init(&shared.nempty, 0, NBUFF);
Sem_init(&shared.nstored, 0, 0);
Set_concurrency(2);
Pthread_create(&tid_produce, NULL, produce, NULL);
Pthread_create(&tid_consume, NULL, consume, NULL);
Pthread_join(tid_produce, NULL);
Pthread_join(tid_consume, NULL);
Sem_destroy(&shared.mutex);
Sem_destroy(&shared.nempty);
Sem_destroy(&shared.nstored);
exit(0);
}
void *produce(void *arg)
{
int i;
for (i = 0; i < nitems; i++) {
Sem_wait(&shared.nempty); /* wait for at least 1 empty slot */
Sem_wait(&shared.mutex);
shared.buff[i % NBUFF] = i; /* store i into circular buffer */
Sem_post(&shared.mutex);
Sem_post(&shared.nstored); /* 1 more stored item */
}
return(NULL);
}
void *consume(void *arg)
{
int i;
for (i = 0; i < nitems; i++) {
Sem_wait(&shared.nstored); /* wait for at least 1 stored item */
Sem_wait(&shared.mutex);
if (shared.buff[i % NBUFF] != i)
printf("buff[%d] = %d\n", i, shared.buff[i % NBUFF]);
Sem_post(&shared.mutex);
Sem_post(&shared.nempty); /* 1 more empty slot */
}
return(NULL);
}
进程间共享信号灯