使用 NSCondition 解锁线程 (Objective-C)
Unlocking a thread using NSCondition (Objective-C)
我正在使用 Objective-C 并尝试使用需要相互通信的线程。
代码如下:
-(id) init
{
self = [super init];
if (self) {
_event = [[MyTestClass alloc]init]; //MyTestClass has a property of type NSCondition
}
return self;
}
-(void) func1
{
NSLog(@"The Function 1 is being called");
NSLog(@"Locking The First function");
[self.event.myCondition lock];
[self.event.myCondition wait];
NSLog(@"Resuming Function 1");
NSLog(@"This is a test 1 ");
NSLog(@"This is a test 2");
NSLog(@"Terminating func 1");
}
-(void) func2
{
NSLog(@"2");
NSLog(@"Hey Hey Hey How are you 0 ");
NSLog(@"Hey Hey Hey How are you 1 ");
NSLog(@"Hey Hey Hey How are you 2");
NSLog(@"Signaling function 1");
[self.event.myCondition signal];
NSLog(@"Hey Hey Hey How are you 3");
NSLog(@"Terminating func 2");
}
我 运行 func1 和 func2 在两个单独的线程上,如下所示
- (void)viewDidLoad {
[super viewDidLoad];
SuperTestClass * n = [[SuperTestClass alloc]init];
// Do any additional setup after loading the view, typically from a nib.
MyTestClass * m = [[MyTestClass alloc]init];
dispatch_queue_t newQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t newGroup = dispatch_group_create();
dispatch_group_async(newGroup, newQueue, ^{
[n func1];
});
dispatch_group_async(newGroup, newQueue, ^{
[n func2];
});
dispatch_group_wait(newGroup, DISPATCH_TIME_FOREVER);
NSLog(@"All process have terminated");
}
当我运行这段代码
时出现以下错误
2015-07-07 19:05:54.528 signalingInObjectiveC[31617:319892] 2
2015-07-07 19:05:54.528 signalingInObjectiveC[31617:319894] The Function 1 is being called
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 0
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319894] Locking The First function
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 1
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Signaling function 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 3
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] Resuming Function 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Terminating func 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] This is a test 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] This is a test 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] Terminating func 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319870] All process have terminated
2015-07-07 19:05:54.535 signalingInObjectiveC[31617:319870] *** -[NSCondition dealloc]: condition (<NSCondition: 0x7fa2aa517180> '(null)') deallocated while still in use
2015-07-07 19:05:54.535 signalingInObjectiveC[31617:319870] *** Break on _NSLockError() to debug.
我想知道我解锁的方式有什么问题。
您滥用了 NSCondition class。检查 apple doc。
本质上,POSIX 条件与保护条件测试的共享数据的互斥锁一起使用。你应该有类似的东西(其中 P 是共享状态的布尔谓词)
线程#1:
[cond lock];
while (!P(state)) {
[cond wait];
}
// invariant: if you get here, P(state) is true
... Use the state... // it is protected by the lock
[cond unlock];
话题 #2:
[cond lock];
... change the state ... // this potentially changes the value of P
[cond signal]; // or [cond broadcast]
[cond unlock];
线程 #2 修改共享状态(例如,将消息存放在共享缓冲区中)并通知线程 #1。在线程#2 放弃锁之前,线程#1 无法唤醒。请注意线程 #1 中的调用 [cond wait] 如何以原子方式解锁互斥量并进入休眠状态。循环是必要的有两个原因:
- 你可能会得到虚假唤醒(无缘无故,所以不能保证 P(state) 是真的。
- 您可以让多个线程执行线程 #1 所描述的操作。如果线程 #2 只存入一条数据,那么只有一个执行消费的线程可以实际获取数据项并且 "consuming it" 将使 P(state) 无效,因此其他线程将立即返回休眠状态。
最重要的是,您的代码不正确,因为您无法解锁条件并且在锁定时销毁了它。您没有遵循使用 POSIX 条件的编码模式。
我正在使用 Objective-C 并尝试使用需要相互通信的线程。
代码如下:
-(id) init
{
self = [super init];
if (self) {
_event = [[MyTestClass alloc]init]; //MyTestClass has a property of type NSCondition
}
return self;
}
-(void) func1
{
NSLog(@"The Function 1 is being called");
NSLog(@"Locking The First function");
[self.event.myCondition lock];
[self.event.myCondition wait];
NSLog(@"Resuming Function 1");
NSLog(@"This is a test 1 ");
NSLog(@"This is a test 2");
NSLog(@"Terminating func 1");
}
-(void) func2
{
NSLog(@"2");
NSLog(@"Hey Hey Hey How are you 0 ");
NSLog(@"Hey Hey Hey How are you 1 ");
NSLog(@"Hey Hey Hey How are you 2");
NSLog(@"Signaling function 1");
[self.event.myCondition signal];
NSLog(@"Hey Hey Hey How are you 3");
NSLog(@"Terminating func 2");
}
我 运行 func1 和 func2 在两个单独的线程上,如下所示
- (void)viewDidLoad {
[super viewDidLoad];
SuperTestClass * n = [[SuperTestClass alloc]init];
// Do any additional setup after loading the view, typically from a nib.
MyTestClass * m = [[MyTestClass alloc]init];
dispatch_queue_t newQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t newGroup = dispatch_group_create();
dispatch_group_async(newGroup, newQueue, ^{
[n func1];
});
dispatch_group_async(newGroup, newQueue, ^{
[n func2];
});
dispatch_group_wait(newGroup, DISPATCH_TIME_FOREVER);
NSLog(@"All process have terminated");
}
当我运行这段代码
时出现以下错误2015-07-07 19:05:54.528 signalingInObjectiveC[31617:319892] 2
2015-07-07 19:05:54.528 signalingInObjectiveC[31617:319894] The Function 1 is being called
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 0
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319894] Locking The First function
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 1
2015-07-07 19:05:54.529 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Signaling function 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Hey Hey Hey How are you 3
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] Resuming Function 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319892] Terminating func 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] This is a test 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] This is a test 2
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319894] Terminating func 1
2015-07-07 19:05:54.530 signalingInObjectiveC[31617:319870] All process have terminated
2015-07-07 19:05:54.535 signalingInObjectiveC[31617:319870] *** -[NSCondition dealloc]: condition (<NSCondition: 0x7fa2aa517180> '(null)') deallocated while still in use
2015-07-07 19:05:54.535 signalingInObjectiveC[31617:319870] *** Break on _NSLockError() to debug.
我想知道我解锁的方式有什么问题。
您滥用了 NSCondition class。检查 apple doc。 本质上,POSIX 条件与保护条件测试的共享数据的互斥锁一起使用。你应该有类似的东西(其中 P 是共享状态的布尔谓词)
线程#1:
[cond lock];
while (!P(state)) {
[cond wait];
}
// invariant: if you get here, P(state) is true
... Use the state... // it is protected by the lock
[cond unlock];
话题 #2:
[cond lock];
... change the state ... // this potentially changes the value of P
[cond signal]; // or [cond broadcast]
[cond unlock];
线程 #2 修改共享状态(例如,将消息存放在共享缓冲区中)并通知线程 #1。在线程#2 放弃锁之前,线程#1 无法唤醒。请注意线程 #1 中的调用 [cond wait] 如何以原子方式解锁互斥量并进入休眠状态。循环是必要的有两个原因:
- 你可能会得到虚假唤醒(无缘无故,所以不能保证 P(state) 是真的。
- 您可以让多个线程执行线程 #1 所描述的操作。如果线程 #2 只存入一条数据,那么只有一个执行消费的线程可以实际获取数据项并且 "consuming it" 将使 P(state) 无效,因此其他线程将立即返回休眠状态。
最重要的是,您的代码不正确,因为您无法解锁条件并且在锁定时销毁了它。您没有遵循使用 POSIX 条件的编码模式。