网站首页 > 技术文章 正文
linux多线程编程-信号量
信号量机制
锁机制使用是有限制的,锁只有两种状态,即加锁和解锁,对于互斥的访问一个全局变量,这样的方式还可以对付,但是要是对于其他的临界资源,比如说多台打印机等,这种方式显然不行了。
信号量机制在操作系统里面学习的比较熟悉了,信号量是一个整数计数器,其数值表示空闲临界资源的数量。
当有进程释放资源时,信号量增加,表示可用资源数增加;当有进程申请到资源时,信号量减少,表示可用资源数减少。这个时候可以把锁机制认为是0-1信号量。
关于信号量机制的函数 初始化信号量
int sem_init(sem_t * sem, int pshared, unsigned int value);
- 成功返回0,失败返回-1;
- 参数sem:表示指向信号结构的指针。
- 参数pshared:不是0 的时候该信号量在进程间共享,否则只能在当前进程的所有线程间共享。
- 参数value:信号量的初始值。
int sem_wait(sem_t *sem); 信号量减一操作,有线程申请资源
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量的指针
int sem_post(sem_t *sem);信号量加一操作,有线程释放资源
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量指针
int sem_destroy(sem_t *sem); 销毁信号量
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量的指针。
信号量来解决多线程的同步问题,程序代码如下
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include <semaphore.h>
void* ticketport1(void*);
void* ticketport2(void*);
int tickets=100;
sem_t mutex,full; //定义两个信号量
int main()
{
int ret;
pthread_t id1,id2;
ret=sem_init(&mutex,0,1); //初始化mutex信号量为1
ret+=sem_init(&full,0,0); //初始化full信号量为0
if(ret!=0)
{
perror("sem_init");
}
ret=pthread_create(&id1,NULL,ticketport1,NULL);
if(ret<0)
{
perror("creat thread1:");
exit(-1);
}
ret=pthread_create(&id2,NULL,ticketport2,NULL);
if(ret<0)
{
perror("creat thread2:");
exit(-1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
return 0;
}
void* ticketport1(void* arg)
{
while(1)
{
sem_wait(&mutex); //mutex信号量进行P操作
if(tickets>0)
{
usleep(1000);
printf("thread1 sell ticket: %d\n",tickets--);
sem_post(&full); //full信号量进行V操作
}
else
{
sem_post(&full); //full信号量进行V操作
break;
}
}
return (void*)0;
}
void* ticketport2(void* arg)
{
while(1)
{
sem_wait(&full); //full信号量进行P操作
if(tickets>0)
{
usleep(1000);
printf("thread2 sell ticket: %d\n",tickets--);
sem_post(&mutex); //mutex信号量进行V操作
}
else
{
sem_post(&mutex); //mutex信号量进行V操作
break;
}
}
return (void*)0;
}
上面的sem_init函数用来初始化两个信号量的初始化值,这里一个设为1,一个设为0,sem_wait类似于P操作,让信号量减1,如果小于结果小 于0,线程阻塞,否则线程继续执行,sem_post类似于V操作,提升信号量的值,加1,通过这两个信号量之间的互相“救对方”,就可以实现这两个线程 的同步执行
经典的生产者消费者问题,只有当生产者把资源放入存储区,消费者才能取得
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define MAXSIZE 10
int stack[MAXSIZE];
int size =0;
sem_t sem;
void privide_data(void)
{
int i;
for(i =0;i<MAXSIZE;++i)
{
stack[i] = i;
sem_post(&sem);
}
}
void handle_data(void)
{
int i;
while((i = size ++) <MAXSIZE)
{
sem_wait(&sem);
printf("cross : %d X %d = %d \n",stack[i],stack[i],stack[i] * stack[i]);
sleep(1);
}
}
int main()
{
pthread_t privider,handler;
sem_init(&sem,0,0);
pthread_create(&privider,NULL,(void *)&privide_data,NULL);
pthread_create(&handler,NULL,(void *)&handle_data,NULL);
pthread_join(privider,NULL);
pthread_join(handler,NULL);
sem_destroy(&sem);
return 0;
}
猜你喜欢
- 2024-10-29 RT-Thread快速入门-互斥量 互斥方案用什么指标
- 2024-10-29 Datenlord |内存顺序问题(二) dataloader 内存
- 2024-10-29 操作系统概论:第二章 进程管理 简述操作系统进程管理,并举例说明
- 2024-10-29 Java多线程操作系统(生产者、消费者问题)
- 2024-10-29 高可用架构-容错机制 容错技术可以提高系统的可靠性
- 2024-10-29 计算机操作系统笔记第二章进程管理中篇
- 2024-10-29 六大进程通信机制总结 进程通信有哪几种基本类型?
- 2024-10-29 Java系统过载保护机制之信号量的控制
- 2024-10-29 铂金04:通风报信-为何说信号量是线程间的同步良器
- 2024-10-29 记一次阿里面试题:都有哪些进程间通信方式?麻烦你不要再背了
你 发表评论:
欢迎- 最近发表
-
- 在 Spring Boot 项目中使用 activiti
- 开箱即用-activiti流程引擎(active 流程引擎)
- 在springBoot项目中整合使用activiti
- activiti中的网关是干什么的?(activiti包含网关)
- SpringBoot集成工作流Activiti(完整源码和配套文档)
- Activiti工作流介绍及使用(activiti工作流会签)
- SpringBoot集成工作流Activiti(实际项目演示)
- activiti工作流引擎(activiti工作流引擎怎么用)
- 工作流Activiti初体验及在数据库中生成的表
- Activiti工作流浅析(activiti6.0工作流引擎深度解析)
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)