如何在iOS中执行多线程?

利班·阿卜杜勒

很抱歉这个问题的标题含糊,我想不出一个简洁的句子来解释我遇到的问题。

基本上,我想启动多个线程,并传递一个可以在该上下文中使用的线程特定值的对象。这是执行此操作的代码

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方法。

但是,您已将其指定selfdelegatefor 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;请参阅并发编程指南》中的“从线程迁移)。

最后的观察。我知道使用NSURLConnectionNSURLSession有一个限制,即您可以执行的并发网络请求数(通常为4或5)是有限的,因此您也可能会警惕使用太多GCDAsyncSocket实例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在iOS Swift中执行多线程,并发或并行处理?

来自分类Dev

(Java多线程)如何在多线程中传递参数?

来自分类Dev

Java仅用于2台计算机的多线程,如何在主线程中执行

来自分类Dev

Java仅用于2台计算机的多线程,如何在主线程中执行

来自分类Dev

iOS - 如何在多线程中正确执行 sqlite3 写操作?

来自分类Dev

如何在Python中实现多线程?

来自分类Dev

如何在Perl中开始多线程

来自分类Dev

GHC如何在多线程应用程序中强制执行评估?

来自分类Dev

如何在同一数组中的随机位置上执行多线程操作?

来自分类Dev

如何在多线程方案中对仅执行一次的代码进行单元测试?

来自分类Dev

GHC如何在多线程应用程序中强制执行评估?

来自分类Dev

多线程:如何在不同的线程中运行不同的功能?

来自分类Dev

如何在多线程应用程序中存储线程

来自分类Dev

多线程iOS中的通知

来自分类Dev

如何在多线程环境中更好地使用ExecutorService?

来自分类Dev

多线程如何在Web环境中工作

来自分类Dev

如何在多线程C ++程序中删除对象

来自分类Dev

如何在Akka和Scala中实现多线程?

来自分类Dev

如何在多线程中为用户提供公平

来自分类Dev

如何在多线程C ++中传递多维数组

来自分类Dev

如何在IntelliJ中调试多线程应用程序?

来自分类Dev

如何在多线程中获得函数结果

来自分类Dev

如何在Java多线程环境中复制ArrayList <T>?

来自分类Dev

c-如何在多线程环境中处理SIGPIPE?

来自分类Dev

如何在Orchard模块中实现多线程?

来自分类Dev

如何在卡布奇诺中多线程

来自分类Dev

如何在多线程中处理n个请求

来自分类Dev

如何在Camel quickfixj组件中启用多线程

来自分类Dev

如何在ONNX Runtime中实现多线程?

Related 相关文章

  1. 1

    如何在iOS Swift中执行多线程,并发或并行处理?

  2. 2

    (Java多线程)如何在多线程中传递参数?

  3. 3

    Java仅用于2台计算机的多线程,如何在主线程中执行

  4. 4

    Java仅用于2台计算机的多线程,如何在主线程中执行

  5. 5

    iOS - 如何在多线程中正确执行 sqlite3 写操作?

  6. 6

    如何在Python中实现多线程?

  7. 7

    如何在Perl中开始多线程

  8. 8

    GHC如何在多线程应用程序中强制执行评估?

  9. 9

    如何在同一数组中的随机位置上执行多线程操作?

  10. 10

    如何在多线程方案中对仅执行一次的代码进行单元测试?

  11. 11

    GHC如何在多线程应用程序中强制执行评估?

  12. 12

    多线程:如何在不同的线程中运行不同的功能?

  13. 13

    如何在多线程应用程序中存储线程

  14. 14

    多线程iOS中的通知

  15. 15

    如何在多线程环境中更好地使用ExecutorService?

  16. 16

    多线程如何在Web环境中工作

  17. 17

    如何在多线程C ++程序中删除对象

  18. 18

    如何在Akka和Scala中实现多线程?

  19. 19

    如何在多线程中为用户提供公平

  20. 20

    如何在多线程C ++中传递多维数组

  21. 21

    如何在IntelliJ中调试多线程应用程序?

  22. 22

    如何在多线程中获得函数结果

  23. 23

    如何在Java多线程环境中复制ArrayList <T>?

  24. 24

    c-如何在多线程环境中处理SIGPIPE?

  25. 25

    如何在Orchard模块中实现多线程?

  26. 26

    如何在卡布奇诺中多线程

  27. 27

    如何在多线程中处理n个请求

  28. 28

    如何在Camel quickfixj组件中启用多线程

  29. 29

    如何在ONNX Runtime中实现多线程?

热门标签

归档