很抱歉这个问题的标题含糊,我想不出一个简洁的句子来解释我遇到的问题。
基本上,我想启动多个线程,并传递一个可以在该上下文中使用的线程特定值的对象。这是执行此操作的代码
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
。这是选择器方法。
- (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
就是为您执行异步套接字通信。似乎没有必要创建自己的线程,让每个线程启动异步写入任务。
实际上,当我阅读您的代码示例时,您的线程将在异步写入启动后终止(但可能在写入完成之前终止),我认为这不是您的意图。
搁置这一点,您会问:
它为一个线程显示0,为所有其他线程显示8,而在该上下文中它们应分别具有唯一的偏移量。
正如sahara108所指出的,您引用的是实例变量_thread_offset
,_thread_bytes
而不是访问您添加到传递给线程的字典中的值。您应该从传递给线程的字典中检索这些值。
另外,线程完成时是否有任何回调方法?
您可以观察NSThreadWillExitNotification
(显然可以编写一个willEndThread
方法):
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEndThread:) name:NSThreadWillExitNotification object:nil];
您显然也必须编写一个willEndThread
方法。
但是,您已将其指定self
为delegate
for GCDAsyncSocket
,因此,如果您希望完成写入请求,则应实现这些委托方法。
看一下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
委托方法即可。
就个人而言,我将感兴趣的是,这是否比在启用流水线的情况下进行正常数据发布更快。我也不太熟悉的特质GCDAsyncSocket
,所以我不知道是否有更深层次的原因为什么他们不希望您使用并发队列,但是以上可能是一种创建多个实例而GCDAsyncSocket
无需钻研的方法进入NSThread
(通常最好使用GCD或操作队列NSThread
;请参阅《并发编程指南》中的“从线程迁移”)。
最后的观察。我知道使用NSURLConnection
并NSURLSession
有一个限制,即您可以执行的并发网络请求数(通常为4或5)是有限的,因此您也可能会警惕使用太多GCDAsyncSocket
实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句