首页 > 编程知识 正文

ios信号量使用,信号量的类型

时间:2023-05-04 11:50:57 阅读:113416 作者:1863

一、信号量简要介绍:

1 .信号量:

“信号”(Semaphore )有时也称为信号,是多线程环境中使用的设施,可用于防止同时调用两个或多个重要代码段。 在进入重要代码段之前,线程必须获取信号量。完成重要代码段后,线程必须释放信号量。 其他想进入这个重要代码段的线程必须等待第一个线程释放信号量。 要完成此过程,必须创建信号VI,并将Acquire Semaphore VI和Release Semaphore VI分别放在每个主要代码段的开头。 确保这些信号量VI参考了最初创建的信号量。

2 .特性:

抽象地说,信号量的特性如下。 信号量是非负整数(车位数),要通过它的所有线程/进程车辆)将减少一个整数,如果该整数值为零,则要通过它的所有线程都处于等待状态。 信号量定义了两个操作:“等待”和“发行”。 当线程调用等待操作时,它将获得资源并减少一个信号量,或继续等待,直到达到或超过临时信号量。 “Release (释放)”实际上是对信号执行正向操作,以支持车辆离开停车场。 之所以将此操作称为“释放”,是因为释放了信号所保护的资源。

3 .说明:

以停车场的运营为例。 为了简单起见,假设停车场只有三辆车,最初有三辆车空着。 此时,如果同时来了5辆车,看门人允许其中3辆直接进入,然后下车停下。 剩下的车要在门口等,后来来的车也要在门口等。 那时,有一辆车出了停车场,看门人知道,可以打开车停下来,把外面的一辆放进去,再分开两辆,再放两辆进去,这样往返。

在这个停车场系统中,车位是公共资源,每辆车就像一个线程,看门人充当信号量。

4 .发展史:

1965年,荷兰学者Edsger Dijkstra提出的信号量(Semaphores )机制是一种有效的过程同步工具,在长期的广泛应用中信号量机制得到了长足发展,它从整数信号量到记录型信号量

5 .在IOs系统GCD的semaphore.h头文件中提供PV操作的三种方法

在IOS系统GCD的semaphore.h头文件中,PV操作//该value提供要初始化的信号数1.dispatch _ semaphore _ create (long value )这三种方法//该方法为p 参数dsema表示哪个信号量为负,如果信号量为0,则等待。 timeout这个参数是等待接收的时间。 2.dispatch _ semaphore _ wait (dispatch _ semaphore _ TD sema,dispatch_time_t timeout ); //该方法在v操作中将信号量加1,参数dsema表示将哪个信号量加13. dispatch _ semaphore _ signal (dispatch _ semaphore _ TD sema ); 6 .常见信号量应用场景

a .锁住(互斥) ) ) ) )。

b .异步返回

c .线程并发行数的控制

示例:用信号或同步锁定互斥多线程操作的iphoneNumber变量

# import ' view controller.h ' @ interfaceviewcontroller (//iphone的数量@property ) nonatomic,assign ) int iphoneNumber //@ end @ implementationviewcontroller-(void ) viewDidLoad { [super viewDidLoad]; self.iphoneNumber=1000; //初始化单个信号self.semaphore=dispatch _ semaphore _ create (1)//在信号中进行互斥,同时打开三个窗口(线程)以实现iphonensthrreate initwithtarget 3360 self selector 3360 @ selector (selector ) selector ) )的thread1.name=@ '窗口1 '; ns thread * thread2=[ [ nsthreadalloc ] initwithtarget : self selector 3360 @ selector (sell iphone ) object : nil ] thread ns thread * thread3=[ [ nsthreadalloc ] initwithtarget : self selector 3360 @ selector (sell iphone ) object : nil ] thread

/// 通过同步锁进行互斥,开启三个窗口(线程)同时卖iphone// NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sellIphoneWithSynchronization) object:nil];// thread1.name = @"窗口1";// NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(sellIphoneWithSynchronization) object:nil];// thread2.name = @"窗口2";// NSThread *thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(sellIphoneWithSynchronization) object:nil];// thread3.name = @"窗口3"; [thread1 start]; [thread2 start]; [thread3 start];}/// 通过信号量达到互斥- (void)sellIphone{ while (1) { // P操作对信号量进行减一,然后信号量变0,限制其他窗口(线程)进入 dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER); if (self.iphoneNumber > 0) // 检查还有没iphone可卖 { NSLog(@"卖出iphone剩下%d台iphone",--self.iphoneNumber); } else { NSLog(@"iphone没有库存了"); return; } // V操作对信号量进行加一,然后信号量为1,其他窗口(线程)就能进入了 dispatch_semaphore_signal(self.semaphore); }}/// 通过同步锁进行互斥,通过同步锁会比通过信号量控制的方式多进入该临界代码(线程数量-1)次- (void)sellIphoneWithSynchronization{ while (1) { @synchronized (self) { if (self.iphoneNumber > 0) // 检查还有没iphone可卖 { NSLog(@"%@卖出iphone剩下%d台iphone",[NSThread currentThread].name,--self.iphoneNumber); } else { NSLog(@"iphone没有库存了"); return; } } }}@end

示例2:

公交车上司机和售票员的配合问题。加锁(互斥)

1.司机需要等待售票员关门后才能开车
2.售票员需要等待司机停车后才能开门

// 司机是否停车的信号量, dispatch_semaphore_t semaphoreStopBused = dispatch_semaphore_create(1); // 售票员是否关门的信号量 dispatch_semaphore_t semaphoreCloseDoored = dispatch_semaphore_create(0); // 拿到全局队列 dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 司机的相关操作 dispatch_async(quene, ^{ while (1) { // 司机等待售票员关门,DISPATCH_TIME_FOREVER表示这个信号量如果是0就一直等待这个信号量 dispatch_semaphore_wait(semaphoreCloseDoored, DISPATCH_TIME_FOREVER); NSLog(@"司机开车"); NSLog(@"司机停车"); // 司机已关门,停车的信号量加一 dispatch_semaphore_signal(semaphoreStopBused); } }); // 售票员的相关操作 dispatch_async(quene, ^{ while (1) { // 售票员等待司机停车 dispatch_semaphore_wait(semaphoreStopBused, DISPATCH_TIME_FOREVER); NSLog(@"售票员开门"); NSLog(@"售票员关门"); // 售票员已经关门,关门的信号量加一 dispatch_semaphore_signal(semaphoreCloseDoored); } });

示例3:

生产和销售的问题(第一种情况加锁(互斥))

/* 生产和销售的线程同时操纵iphoneNumber变量为了保证数据的正确性,并且生产到5台iphone就不再生产了。 */ // iphone数量 __block int iphoneNumber = 0; // 生产和销售的互斥 dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); // 拿到全局队列 dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 生产iphone dispatch_async(quene, ^{ while (1) { // 生产和销售的互斥,等待信号量 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); if (iphoneNumber < 5) { NSLog(@"生产iphone,目前有%d台",++iphoneNumber); } dispatch_semaphore_signal(semaphore); } }); // 销售iphone dispatch_async(quene, ^{ while (1) { // 生产和销售的互斥,等待信号量 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); if (iphoneNumber > 0) { NSLog(@"卖掉一台iphone,目前有%d台",--iphoneNumber); } dispatch_semaphore_signal(semaphore); } });

 

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。