- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想使用 NSThread
实现以下任务
我有一个主线程和三 (3) 个 workerThread T1、T2、T3。所有这些同时从主线程开始,主线程有一个int size
变量。现在我想以一种方式同步所有三个线程,当我的上述每个线程执行时,它将打印以下内容:
//在主线程中
- (void) mainFunction{
size = 0;
NSThread* T1 = [[NSThread alloc] initWithTarget:self
selector:@selector(workerThread:)
object:@"T1"];
[T1 start];
NSThread* T2 = [[NSThread alloc] initWithTarget:self
selector:@selector(workerThread:)
object:@"T2"];
[T2 start];
NSThread* T3 = [[NSThread alloc] initWithTarget:self
selector:@selector(workerThread:)
object:@"T3"];
[T3 start];
}
//工作线程
- (void) workerThread:(id)obj{
size++;
NSLog(@"Thread:%@--------Size:%d,obj,size)
}
我想要以下输出:
Thread:T1-------Size:1
Thread:T2-------Size:2
Thread:T3-------Size:3
Thread:T1-------Size:4
Thread:T2-------Size:5
Thread:T3-------Size:6
Thread:T1-------Size:7
Thread:T2-------Size:8
Thread:T3-------Size:9
当size=10
最佳答案
几个想法:
您说“当 size=10 时将控制返回给主线程”。这不太合理。主线程永远不会“失去”控制(因为这些线程是同时发生的)。也许您希望在出现这种情况时在主线程上发生一些事情?
您没有让 workerThread
方法执行任何循环,因此在您编写它时,每个线程将执行一次然后退出。您可能需要在此处添加某种形式的循环。
即使您添加了循环,您所需的输出表明您假设将发生特定的操作序列,即这三个线程将按顺序运行(但您没有这样的保证)。如果您需要这种行为,您可以设置一系列信号量,通过这些信号量您可以让一个线程等待另一个线程发送信号。
从不同的线程更新变量时应该小心。查看Synchronization Threading Programming Guide 的部分。 在处理像计数器这样的基本数据类型时,它得到了简化(只需确保将其声明为 atomic
)。但在更实质性的场景中,您需要使用一些同步技术,例如 @synchronized
、锁、专用自定义串行队列等。
一般来说,如果您正在使用线程(但如果使用队列则不是必需的),您应该是 creating an autorelease pool为你的主题。
无论如何,撇开这些观察不谈,您可能会得到类似下面的东西,其中 (a) 有 @autoreleasepool
; (b) 循环; (c) 使用锁来确保各个线程同步它们与 size
变量的交互:
- (void) workerThread:(id)obj
{
@autoreleasepool {
BOOL done = NO;
while (!done) {
[self.lock lock];
if (size < 9) {
size++;
NSLog(@"Thread:%@--------Size:%d", obj, size);
}
else
{
done = YES;
}
[self.lock unlock];
// perhaps you're doing something time consuming here...
}
}
}
假设你有 NSLock
属性,叫做 lock
:
@property (nonatomic, strong) NSLock *lock;
您在启动线程测试之前创建的:
- (void) threadTest
{
size = 0;
self.lock = [[NSLock alloc] init];
NSThread* T1 = [[NSThread alloc] initWithTarget:self selector:@selector(workerThread:) object:@"T1"];
[T1 start];
NSThread* T2 = [[NSThread alloc] initWithTarget:self selector:@selector(workerThread:) object:@"T2"];
[T2 start];
NSThread* T3 = [[NSThread alloc] initWithTarget:self selector:@selector(workerThread:) object:@"T3"];
[T3 start];
}
说了这么多,您从“将控制权返回主线程”开始。正如我之前所说,确实没有必要这样做,因为在您的示例中,您的应用程序的主线程从未放弃控制
为了控制发生在不同线程上的任务之间的关系,我可能建议使用 GCD 或操作队列。它们更易于使用并且具有更好的机制来控制各种任务/操作之间的依赖关系(参见 Concurrency Programming Guide )。
例如,考虑与上述 workerThread
方法等效的基于操作的方法(相同,但不需要自动释放池):
- (void) operationMethod:(id)obj
{
BOOL done = NO;
while (!done) {
[self.lock lock];
if (size < 9) {
size++;
NSLog(@"Operation:%@--------Size:%d", obj, size);
}
else
{
done = YES;
}
[self.lock unlock];
// perhaps you're doing something time consuming here...
}
}
然后您可以创建三个操作(可能会在三个线程上运行)并等待结果,如下所示:
- (void) operationTestWait
{
size = 0;
self.lock = [[NSLock alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op1"];
NSOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op2"];
NSOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op3"];
[queue addOperations:@[op1, op2, op3] waitUntilFinished:YES];
// do here whatever should happen when the operations are done
}
在这种情况下,主线程将等待这三个操作完成。
或者,更好的是,如果这些任务花费的时间超过几毫秒,你不应该让主队列等待(因为你应该永远阻塞主队列),而是,你应该简单地定义当这三个操作完成时,你希望主队列做什么:
- (void) operationTest
{
size = 0;
self.lock = [[NSLock alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op1"];
NSOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op2"];
NSOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationMethod:) object:@"Op3"];
NSOperation *completion = [NSBlockOperation blockOperationWithBlock:^{
// if you want this to do something on the main queue, then have this add it to the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// do here whatever should happen when the operations are done
}];
}];
// define this completion operation to be dependent upon the above three operations
[completion addDependency:op1];
[completion addDependency:op2];
[completion addDependency:op3];
// now add all of them, but don't wait until finished;
// but the completion operation will only start when its dependencies
// are resolved
[queue addOperations:@[op1, op2, op3, completion] waitUntilFinished:NO];
}
原谅冗长的回答。如果你能给我们一个更实际的例子,说明这些不同的线程将做什么,我们就可以就如何最好地解决它提供更好的建议。但是,一般来说,操作队列或调度队列可能是解决大多数并发相关挑战的更有效方法。
关于ios - 多个 NSThreads 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19284249/
我有几个线程。我想运行它们以确保它们正在一个接一个地执行。[运行线程1];[运行线程2];当我这样做时,线程 2 正在运行,而无需等待线程 1 完成。我需要这个,因为我需要线程 1 中的值,以便在线程
NSThread 异步下载图片 在IOS中处理多线程有三个方案 , NSThread 、NSOperation 、GCD 。当然GCD应该是最方便的 ,我们一个一个学 。先理解底层的,最后再使用最方便
我正在创建一个新线程,它在每隔一段时间后运行我的一个方法。 现在我正在做的事情如下: NSThread *thread = [[NSThread alloc] initWithTarget:self
我正在开发一款游戏模拟游戏,希望加快比赛模拟速度。在给定日期,可能有 50 多场比赛需要模拟。目前,我循环遍历每个并告诉他们模拟自己,但这可能需要很长时间。我本来希望 1) 覆盖“忙碌”屏幕 2) 为
我有一个 iPhone 应用程序,在其中显示一个从 RSS 提要加载的表格 View 。当 View 加载时,我调用此方法在新的 NSThread 中运行: - (void)start:(NSURL*
是否可以在单独的线程中运行类方法(以“+”开头)?通常我调用像 [myClass myController]; 这样的方法,我尝试了 [NSThread detachNewThreadSelector
我正在使用 NSOperationQueue 来管理一个相当长的 iOS 应用程序阶段,所以我想异步管理它。在那个阶段,我通过直接使用 calloc 函数在 C 中分配大数组。“大”是指 1024x2
为什么我线程的 Retain count = 2?它在启动方法后增加,为什么? Retain 计数如何为 NSThreads 工作 @implementation ViewController - (
因为 NSThread 无法连接 我尝试了下一个方法,它似乎工作正常,但仍然是非常糟糕的解决方案还是足够好? // init thread NSThread *mythread = [[NSThrea
使用 4 NSThread 将 1000 个元素(例如整数元素)添加到数组中。如果添加一个对象需要 1 个时间单位,那么添加 1000 个对象将需要 1000 个时间单位。通过使用 4 个线程,我想将
我目前正在学习IOS Threading编程......我遇到了一个问题: 我的代码来了,请看一下: int main(int argc, const char * argv[]) { @au
这是我创建线程的方式: readFromWebThread = [[NSThread alloc] initWithTarget:self selector:@selector(loadThread:
我有一个触发线程的静态对象,但每当线程尝试执行选择器时,我都会收到“[NSThread initWithTarget:selector:object:]: target does not implem
我正在处理其他人的代码。我遇到了一行代码 [NSThread detachNewThreadSelector:@selector(myMethod) toTarget:self withObject:
我有很多 NSThreads,我想在它们工作的时候 sleep 。我该怎么做? iOS SDK 中是否有 WinApi 函数 WaitForSingleObject/WaitForMultipleOb
我有一个函数,当我的应用程序进入后台模式时它会被调用。如果用户重新打开应用程序,我想停止线程。到目前为止,我尝试的任何方法都不起作用。 到目前为止,这是我的代码: class Neversleep {
我从购买的媒体流 SDK 库中获得 C++ 回调,它在内部创建了多个线程。 具体来说,当库想要记录一条消息时,我会收到回调。有时我在某些 NSThread 的上下文中被调用,那里有一个自动释放池,但有
我正在使用这样的线程, [NSThread detachNewThreadSelector:@selector(myfunction) toTarget:self withObject 线程运行正常,
我想创建一个不是主线程的工作线程,这样我就可以调用 ... [self performSelector:@selector(doStuff) OnThread:self.myWorkerThread
我正在开发一个应用程序,它在读取 XML 文件时使用 NSThread 加载 viewControllers 的内容。 我是这样完成的: -(void)viewDidAppear:(BOOL)anim
我是一名优秀的程序员,十分优秀!