抱歉,这个问题的标题含糊不清,我想不出一个简洁的句子来解释我遇到的问题。
基本上我想启动多个线程并传递一个对象,该对象具有我可以在该上下文中使用的特定于线程的值。这是执行此操作的代码
while (count < no_threads) {
_thread_bytes = _file_length / no_threads;
_thread_offset = count * _thread_bytes;
NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:_thread_offset],@"thread_offset",
[NSNumber numberWithInt:_thread_bytes], @"thread_bytes",
[NSNumber numberWithInt:count], @"count", nil];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(processServerThread:) object:args];
[thread start];
count++;
}
每个线程都使用正确的 thread_bytes
和 thread_offset
调用选择器方法,并且还可以访问 GCDAsyncSocket
套接字,因此这会导致许多使用 thread_bytes
和 thread_offset
的委托(delegate)方法调用。这是选择器方法。
- (void)processServerThread:(id)sender
{
NSError *err;
dispatch_queue_t iQueue = dispatch_queue_create("main_server_queue", NULL);
GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:iQueue];
if (![socket connectToHost:@"example.com" onPort:8080 error:&err]) {
NSLog(@"Error: couldn't connect to file server....");
return;
}
NSData *message =[[self requestMessageWithOffset:[NSNumber numberWithInt:_thread_offset]
andBytes:[NSNumber numberWithInt:_thread_bytes]]
dataUsingEncoding:NSUTF8StringEncoding];
[socket writeData:message withTimeout:SOCKET_TIMEOUT tag:TAG_FILE_REQUEST_WRITE];
}
如果有 N 个线程正在处理,当我发送请求消息时 _thread_offset
的值,例如,如果偏移量为 0、2、4、8。对于一个线程,它显示 0 和 8对于所有其他线程,虽然它们在该上下文中都应该有一个唯一的偏移量。
还有,线程结束的时候有回调方法吗?
最佳答案
我完全不清楚您为什么要创建这些线程。 GCDAsyncSocket
背后的整点就是给你做异步套接字通信。似乎没有必要创建自己的线程,让每个线程都启动异步写入任务。
事实上,当我阅读您的代码示例时,您的线程将在异步写入启动后立即终止(但可能在写入完成之前),我认为这不是您的意图。
抛开这个,你问:
It shows 0 for one thread an 8 for all other threads, while they should have each a unique offset within that context.
正如 sahara108 所指出的,您正在引用实例变量 _thread_offset
和 _thread_bytes
而不是访问您添加到传递给线程的字典中的值。您应该从传递给线程的字典中检索这些值。
Also, is there any callback method for when a thread finishes?
可以观察NSThreadWillExitNotification
(显然写了一个 willEndThread
方法):
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEndThread:) name:NSThreadWillExitNotification object:nil];
你显然必须写一个 willEndThread
方法也是如此。
但是您指定了 self
作为delegate
对于 GCDAsyncSocket
,所以如果您正在寻找写请求的完成,您应该实现这些委托(delegate)方法。
浏览 GCDAsyncSocket
源,看起来他们希望您使用串行队列。因此,如果您希望并发请求继续运行,您可以尝试如下操作:
_thread_bytes = _file_length / no_threads;
for (int i = 0; i < no_threads; i++) {
_thread_offset = i * _thread_bytes;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL success = [self processRequestWithOffset:_thread_offset byteCount:_thread_bytes];
if (!success) {
// do here whatever you want if the connection was unsuccessful
}
}
}
在哪里
- (BOOL)processRequestWithOffset:(NSInteger)offset byteCount:(NSInteger)byteCount
{
NSError *error;
dispatch_queue_t queue = dispatch_queue_create("main_server_queue", NULL);
GCDAsyncSocket *socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:queue];
if (![socket connectToHost:@"example.com" onPort:8080 error:&error]) {
NSLog(@"Error: couldn't connect to file server: %@", error);
return NO;
}
NSData *message = [[self requestMessageWithOffset:@(offset)
andBytes:@(byteCount)
dataUsingEncoding:NSUTF8StringEncoding];
[socket writeData:message withTimeout:SOCKET_TIMEOUT tag:TAG_FILE_REQUEST_WRITE];
return YES;
}
如果您想知道每个连接是否成功完成,只需执行相关的GCDAsyncSocket
即可。委托(delegate)方法。
就我个人而言,我很想看看这是否比打开流水线进行正常的数据发布更快。我也不是很熟悉 GCDAsyncSocket
的特质,所以我不知道他们不希望您使用并发队列是否有更深层次的原因,但以上可能是创建 GCDAsyncSocket
的多个实例的一种方法无需深入研究NSThread
(GCD 或操作队列通常优于 NSThread
;请参阅 并发编程指南 中的 Migrating Away From Threads)。
最后的观察。我知道 NSURLConnection
和 NSURLSession
您可以执行多少个并发网络请求是有限制的(通常是 4 或 5 个),因此您可能会小心使用太多 GCDAsyncSocket
实例也是如此。
关于ios - 如何在 iOS 中实现多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22685076/