zoukankan      html  css  js  c++  java
  • [IOS笔记] 关于线程

    可以代替自己创建线程的有多种方法,可以管理thread或者通知或者另开进程。

    Technology

    Description

    Operation objects

    Introduced in OS X v10.5, an operation object is a wrapper for a task that would normally be executed on a secondary thread. This wrapper hides the thread management aspects of performing the task, leaving you free to focus on the task itself. You typically use these objects in conjunction with an operation queue object, which actually manages the execution of the operation objects on one or more threads.

    For more information on how to use operation objects, see Concurrency Programming Guide.

    Grand Central Dispatch (GCD)

    Introduced in Mac OS x v10.6, Grand Central Dispatch is another alternative to threads that lets you focus on the tasks you need to perform rather than on thread management. With GCD, you define the task you want to perform and add it to a work queue, which handles the scheduling of your task on an appropriate thread. Work queues take into account the number of available cores and the current load to execute your tasks more efficiently than you could do yourself using threads.

    For information on how to use GCD and work queues, see Concurrency Programming Guide

    Idle-time notifications

    For tasks that are relatively short and very low priority, idle time notifications let you perform the task at a time when your application is not as busy. Cocoa provides support for idle-time notifications using theNSNotificationQueue object. To request an idle-time notification, post a notification to the defaultNSNotificationQueue object using the NSPostWhenIdle option. The queue delays the delivery of your notification object until the run loop becomes idle. For more information, see Notification Programming Topics.

    Asynchronous functions

    The system interfaces include many asynchronous functions that provide automatic concurrency for you. These APIs may use system daemons and processes or create custom threads to perform their task and return the results to you. (The actual implementation is irrelevant because it is separated from your code.) As you design your application, look for functions that offer asynchronous behavior and consider using them instead of using the equivalent synchronous function on a custom thread.

    Timers

    You can use timers on your application’s main thread to perform periodic tasks that are too trivial to require a thread, but which still require servicing at regular intervals. For information on timers, see “Timer Sources.”

    Separate processes

    Although more heavyweight than threads, creating a separate process might be useful in cases where the task is only tangentially related to your application. You might use a process if a task requires a significant amount of memory or must be executed using root privileges. For example, you might use a 64-bit server process to compute a large data set while your 32-bit application displays the results to the user.

    ios中三种创建进程的方法

    Technology

    Option

    Cocoa

    In iOS and OS X v10.5 and later, allocate and initialize an NSThread object (do not use thedetachNewThreadSelector:toTarget:withObject: method). Before calling the start method of the thread object, use the setStackSize: method to specify the new stack size.

    POSIX

    Create a new pthread_attr_t structure and use the pthread_attr_setstacksize function to change the default stack size. Pass the attributes to the pthread_create function when creating your thread.

    Multiprocessing Services

    Pass the appropriate stack size value to the MPCreateTask function when you create your thread.

    ios中,线程和c++,java中类似,需要有一个入口,

    需要分配空间,kenel,programe space

    官网资料:

    Item

    Approximate cost

    Notes

    Kernel data structures

    Approximately 1 KB

    This memory is used to store the thread data structures and attributes, much of which is allocated as wired memory and therefore cannot be paged to disk.

    Stack space

    512 KB (secondary threads)

    8 MB (OS X main thread)

    1 MB (iOS main thread)

    The minimum allowed stack size for secondary threads is 16 KB and the stack size must be a multiple of 4 KB. The space for this memory is set aside in your process space at thread creation time, but the actual pages associated with that memory are not created until they are needed.

    Creation time

    Approximately 90 microseconds

    This value reflects the time between the initial call to create the thread and the time at which the thread’s entry point routine began executing. The figures were determined by analyzing the mean and median values generated during thread creation on an Intel-based iMac with a 2 GHz Core Duo processor and 1 GB of RAM running OS X v10.5.

    当然包括了你写线程花费的时间,有可能你因此要修改你的架构,所以如果线程不是跑得频繁,尽量不要创建。

    创建Thread

    1. detachNewThreadSelector

    [NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];

    2. NSThread

    NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                            selector:@selector(myThreadMainMethod:)
                                            object:nil];
    [myThread start];  // Actually create the thread

    线程之间通信

    performSelector:onThread:withObject:waitUntilDone: 

    3. 可以通过NSObject 创建一个线程

    [myObj performSelectorInBackground:@selector(doSomething) withObject:nil];

    立即执行

    4. POSIX创建线程

    #include <assert.h>
    #include <pthread.h>
     
    void* PosixThreadMainRoutine(void* data)
    {
        // Do some work here.
     
        return NULL;
    }
     
    void LaunchThread()
    {
        // Create the thread using POSIX routines.
        pthread_attr_t  attr;
        pthread_t       posixThreadID;
        int             returnVal;
     
        returnVal = pthread_attr_init(&attr);
        assert(!returnVal);
        returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        assert(!returnVal);
     
        int     threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, NULL);
     
        returnVal = pthread_attr_destroy(&attr);
        assert(!returnVal);
        if (threadError != 0)
        {
             // Report an error.
        }
    }

    如果只使用POSIX,cocoa会不知道你使用多线程,可能会有不稳定状况发生,所以创建一个NSThread,尽管什么都没做。

    分配线程空间

    如果你不满意系统分配的空间,可以手动分配

    Technology

    Option

    Cocoa

    In iOS and OS X v10.5 and later, allocate and initialize an NSThread object (do not use thedetachNewThreadSelector:toTarget:withObject: method). Before calling the start method of the thread object, use the setStackSize: method to specify the new stack size.

    POSIX

    Create a new pthread_attr_t structure and use the pthread_attr_setstacksize function to change the default stack size. Pass the attributes to the pthread_create function when creating your thread.

     设置优先级

    For Cocoa threads, you can use thesetThreadPriority: class method of NSThread to set the priority of the currently running thread. For POSIX threads, you use thepthread_setschedparam function. For more information, see NSThread Class Reference or pthread_setschedparam man page.

     

    线程中的全局变量

    可以在线程中任何地方访问

    threadDictionary method of an NSThread object to retrieve an NSMutableDictionary object, to which you can add any keys required by your thread.

    In POSIX, you use the pthread_setspecific and pthread_getspecific functions to set and get the keys and values of your thread.

    • mmutable objects are generally thread-safe. Once you create them, you can safely pass these objects to and from threads. On the other hand, mutable objects are generally not thread-safe. To use mutable objects in a threaded application, the application must synchronize appropriately. For more information, see “Mutable Versus Immutable.”

    • Many objects deemed “thread-unsafe” are only unsafe to use from multiple threads. Many of these objects can be used from any thread as long as it is only one thread at a time. Objects that are specifically restricted to the main thread of an application are called out as such.

    以下转自:http://marshal.easymorse.com/archives/4700 

    runloop可以阻塞线程,等待其他线程执行后再执行。

    比如:

    @implementation ViewController{
        BOOL end;
    }

    – (void)viewDidLoad
    {
        [super viewDidLoad]; 
        NSLog(@”start new thread …”);
        [NSThread detachNewThreadSelector:@selector(runOnNewThread) toTarget:self withObject:nil];    
        while (!end) {
            NSLog(@”runloop…”);
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            NSLog(@”runloop end.”);
        }
        NSLog(@”ok.”);
    }
    -(void)runOnNewThread{
         NSLog(@”run for new thread …”);
        sleep(1);
        end=YES;
        NSLog(@”end.”);
    }

    但是这样做,运行时会发现,while循环后执行的语句会在很长时间后才被执行。

    那是不是可以这样:

    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];

    缩短runloop的休眠时间,看起来解决了上面出现的问题。

    不过这样也又问题,runloop对象被经常性的唤醒,这违背了runloop的设计初衷。runloop的作用就是要减少cpu做无谓的空转,cpu可在空闲的时候休眠,以节约电量。

    那么怎么做呢?正确的写法是:

    -(void)runOnNewThread{

         NSLog(@”run for new thread …”);
        sleep(1);
        [self performSelectorOnMainThread:@selector(setEnd) withObject:nil waitUntilDone:NO];
        NSLog(@”end.”);
    }
    -(void)setEnd{
        end=YES;
    }

    见黑体斜体字部分,要将直接设置变量,改为向主线程发送消息,执行方法。问题得到解决。

    这里要说一下,造成while循环后语句延缓执行的原因是,runloop未被唤醒。因为,改变变量的值,runloop对象根本不知道。延缓的时长总是不定的,这是因为,有其他事件在某个时点唤醒了主线程,这才结束了while循环。那么,向主线程发送消息,将唤醒runloop,因此问题就解决了。

     

  • 相关阅读:
    day21
    day19
    【淘淘商城项目】jsonp解决ajax跨域问题
    【淘淘商城项目】商品规格参数的表结构设计
    打印日志的时机
    【javascript】call和apply的区别
    MySQL timestamp自动更新时间
    spring管理属性配置文件properties——PropertiesFactoryBean和PropertyPlaceholderConfigurer的区别
    【Maven】修改nexus默认的工作目录
    URIEncoding和UseBodyEncodingForURI的解释
  • 原文地址:https://www.cnblogs.com/zengyou/p/2763077.html
Copyright © 2011-2022 走看看