线程同步——信号量

参考学习资料:进程线程互斥与同步

1.信号量

mutex初始化后为0;上锁后+1,解锁后-1;mutex只能串行。

信号量可以并行,运行多个线程同时访问共享资源。 

1.1 头文件

#include <semaphore.h>

1.2 变量类型

//类型名  变量名
sem_t sem;

1.3 主要函数

(1)初始化信号量

sem_init(sem_t* sem, 
        int pshared, //0-线程同步;1-进程同步
        unsigned int value);//最多有几个线程共享操作数据

(2) 销毁信号量

sem_destroy(sem_t* sem);

(3) 加锁

sem_wait(sem_t* sem);

调用一次相当于对sem做--(减减)操作,如果value=5,最多5个线程。

如果sem值为0,线程会阻塞。

(4) 尝试加锁

sem_trywait(sem_t* sem);

sem==0,加锁失败,不阻塞,直接返回。

(5) 限时尝试加锁

sem_timedwait(sem_t* sem,xxxx);

(6)解锁

sem_post(sem_t* sem);

对sem进行++操作。

2. 代码示例(C语言)

//消费者,生产者模型 
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <windows.h>
#include <semaphore.h>
//创建节点的结构
typedef struct node{
	int data;
	struct node* next;
}Node;

//定义一个指针,指向链表头部
Node* head=NULL; 
//定义两个信号量 
sem_t customer_sem, producer_sem; 

 //生产者 
void* producer(void* arg){
	while(1){
		//使用信号量 完成线程的阻塞 
		sem_wait(&producer_sem);
		//创建一个链表的节点
		Node* pnew=(Node*)malloc(sizeof(Node)); 
		//节点初始化
		pnew->data=rand()%1000;
		pnew->next=head;
		head=pnew;//节点被插入到链表头部
		printf("===== produce: %lu, %d\n",pthread_self(),pnew->data); 
		sem_post(&customer_sem);//customer_sem++
		sleep(rand()%5);
	} 
	
	return NULL;
}

void* customer(void* arg){
	while(1){
		
		sem_wait(&customer_sem);//==0阻塞 
		//链表不为空,删除头节点 
		Node* pdel=head;
		head=head->next;
		printf("===== customer: %lu, %d\n",pthread_self(),pdel->data); 
		free(pdel);
		sem_post(&producer_sem);
		sleep(rand()%5);
	}
	
	return NULL;
}

int main(void){
	int i=0;
	pthread_t thrd[2];
	sem_init(&customer_sem,0,0);
	sem_init(&producer_sem,0,4);
	//创建生产者线程
	pthread_create(&thrd[0],NULL,producer,NULL); 
	pthread_create(&thrd[1],NULL,customer,NULL); 
	
	
	//阻塞回收
	for(;i<2;i++){
		pthread_join(thrd[i],NULL);
	}
	//销毁信号量 
	sem_destroy(&customer_sem);
	sem_destroy(&producer_sem);
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值