Linux多线程14-信号量
信号量的类型 sem_t
int sem_init(sem_t *sem, int pshared, unsigned int value);
初始化信号量
参数:
- sem: 信号量变量地址
- pshared: 0 用在线程间, 非0 用在进程间
- value: 信号量中的值
int sem_destroy(sem_t *sem);
释放资源
int sem_wait(sem_t *sem);
对信号量加锁,调用一次对信号量的值-1, 如果值为0,就阻塞
int sem_trywait(sem_t *sem);
尝试,如果是0资源不可用,阻塞
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
阻塞多长时间
int sem_post(sem_t *sem);
对信号量解锁,调用一次对信号量的值+1
int sem_getvalue(sem_t *sem, int *sval);
获取信号量值
代码示例
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
//创建互斥量
pthread_mutex_t mutex;
//创建两个信号量
sem_t psem;
sem_t csem;
struct Node{
int num;
struct Node* next;
};
//头节点
struct Node* head = NULL;
void* producer(void* arg){
//往容器中添加内容
//不断的创建新节点, 添加到链表中
while(1){
//生产-1 ,最终生产8个
sem_wait(&psem);
pthread_mutex_lock(&mutex);
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode -> next = head;
head = newNode;
newNode -> num = rand()%1000;
printf("add node, num: %d, tid: %ld\n", newNode->num, pthread_self());
pthread_mutex_unlock(&mutex);
//消费+1,最终消费8个
sem_post(&csem);
usleep(100);
}
return NULL;
}
void* customer(void* arg){
//从容器中消费内容
while(1){
//消费-1,告诉生产者又消费了1个
sem_wait(&csem);
pthread_mutex_lock(&mutex);
//保存头节点指针
struct Node* tmp = head;
head = head->next;
printf("delete node, num: %d, tid: %ld\n", tmp->num, pthread_self());
free(tmp);
pthread_mutex_unlock(&mutex);
//生产+1, 告诉生产者多1个空位可以生产
sem_post(&psem);
usleep(100);
}
return NULL;
}
int main(){
pthread_mutex_init(&mutex, NULL);
sem_init(&psem, 0, 8);
sem_init(&csem, 0, 0);
//5个生产者线程, 5个消费者线程
pthread_t ptid[5], ctid[5];
int i;
for(i=0; i<5; i++){
pthread_create(&ptid[i], NULL, producer, NULL);
pthread_create(&ctid[i], NULL, customer, NULL);
}
for(i=0; i<5; i++){
pthread_detach(ptid[i]);
pthread_detach(ctid[i]);
}
while(1){
sleep(10);
}
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
return 0;
}