在进程通信当中,我经常会用到信号灯的操作,为此,我小结一下:
信号灯有无名信号灯和有名信号灯,我们仅讨论无名信号灯,
创建信号灯:
int sem_init(sem_t *sem, int pshared, unsigned int value);
sem表示信号灯的一些信息,类似于进程的PCB。
pshared表示是否为多进程所共享,而不仅仅是一个用于一个进程,linux Thread下没有实现多进程的信号灯共享,所以这个值一般为0,否则会返回-1错误值。
value表示信号灯的数量。
注销信号灯:
int sem_destroy(sem_t *sem);
sem表示要注销的信号灯。
获取灯值:
int sem_getvalue(sem_t *sem, int *sval);
读取sem灯的灯计数。
点灯操作:
int sem_post(sem_t *sem);
给灯值原子加1,表示增加了一个可用的资源。
灭灯操作:
int sem_wai(sem_t *sem);
int sem_trywait(sem_t *sem);
这两个都是将信号灯的原子值减1,表示减少一个可用的资源。但这两个也是有区别的:如果当信号灯的原子值小于或等于0,使用sem_trywait()时不会使线程阻塞,而sem_wait()时将会使线程阻塞。
有关信号灯的操作一般都在头文件
当中,下面是人sem_t的结构体定义:
typedef union
{
char __size[__SIZEOF_SEM_T];
long int __align;
} sem_t;
一个实例:生产者-消费者(经典IPC问题)
/*
*Time:2010/9/27
*Author:Software Engineering
*/
#include <stdio.h>
#include <string.h>
#include <pthread.h> //包含线程操作的一些函数
#include <semaphore.h> //包含信号灯操作的一些函数
#define N 4 //定义缓冲池的数量
#define P_COUNT 3 //定义生产者的数量
#define C_COUNT 3 //定义消费者的数量
int first = 0; //记录缓冲区的下标
char buffer[N][20]; //缓冲区的定义
pthread_mutex_t mutex; //互斥锁
sem_t full, empty; //分别表示缓冲池中的空区和满区的数量
void print()
{
int i;
for(i = 0; i < N; i++) {
printf("%s\t", buffer[i]);
}
printf("\n");
}
void *producer()
{
char *goods = "鸡蛋";
int count = 8;
do {
sem_wait(&empty); //关灯操作
pthread_mutex_lock(&mutex);
strcpy(buffer[first++], goods);
printf("%u生产者:", pthread_self());
print();
sleep(1);
pthread_mutex_unlock(&mutex);
sem_post(&full); //开灯操作
} while(count-- > 0);
}
void *customer()
{
int count = 8;
do {
sem_wait(&full); //关灯操作
pthread_mutex_lock(&mutex);
strcpy(buffer[--first], "0");
printf("%u消费者:", pthread_self());
print();
sleep(1);
pthread_mutex_unlock(&mutex);
sem_post(&empty); //开灯操作
} while(count-- > 0);
}
int main()
{
pthread_t tid1, tid2;
int i;
//初始化缓冲池
for(i = 0; i < N; i++) {
strcpy(buffer[i], "0");
}
//创建信号灯
sem_init(&empty, 0, N);
sem_init(&full, 0, 0);
//创建生产者线程和消费者线程
for(i = 0; i < P_COUNT; i++) {
pthread_create(&tid1, NULL, producer, NULL);
}
for(i = 0; i < C_COUNT; i++) {
pthread_create(&tid2, NULL, customer, NULL);
}
pthread_exit(0);
}
|
运行的部分结果:
3068443504生产者:鸡蛋 鸡蛋 鸡蛋 0
3026484080消费者:鸡蛋 鸡蛋 0 0
3026484080消费者:鸡蛋 0 0 0
3047463792消费者:0 0 0 0
3068443504生产者:鸡蛋 0 0 0
3068443504生产者:鸡蛋 鸡蛋 0 0
3068443504生产者:鸡蛋 鸡蛋 鸡蛋 0
3057953648生产者:鸡蛋 鸡蛋 鸡蛋 鸡蛋
3026484080消费者:鸡蛋 鸡蛋 鸡蛋 0
3068443504生产者:鸡蛋 鸡蛋 鸡蛋 鸡蛋
3047463792消费者:鸡蛋 鸡蛋 鸡蛋 0
3047463792消费者:鸡蛋 鸡蛋 0 0
3047463792消费者:鸡蛋 0 0 0
阅读(1822) | 评论(0) | 转发(0) |