[IOS笔记] - 关于线程
2012-11-12 16:20
531 查看
可以代替自己创建线程的有多种方法,可以管理thread或者通知或者另开进程。
ios中三种创建进程的方法
ios中,线程和c++,java中类似,需要有一个入口,
需要分配空间,kenel,programe space
官网资料:
当然包括了你写线程花费的时间,有可能你因此要修改你的架构,所以如果线程不是跑得频繁,尽量不要创建。
创建Thread
1. detachNewThreadSelector
2. NSThread
线程之间通信
3. 可以通过NSObject 创建一个线程
立即执行
4. POSIX创建线程
如果只使用POSIX,cocoa会不知道你使用多线程,可能会有不稳定状况发生,所以创建一个NSThread,尽管什么都没做。
分配线程空间
如果你不满意系统分配的空间,可以手动分配
设置优先级
For Cocoa threads, you can use the
线程中的全局变量
可以在线程中任何地方访问
In POSIX, you use the
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,因此问题就解决了。
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 theNSNotificationQueueobject. To request an idle-time notification, post a notification to the default NSNotificationQueueobject using the NSPostWhenIdleoption. 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. |
Technology | Option |
---|---|
Cocoa | In iOS and OS X v10.5 and later, allocate and initialize an NSThreadobject (do not use the detachNewThreadSelector:toTarget:withObject:method). Before calling the startmethod of the thread object, use the setStackSize:method to specify the new stack size. |
POSIX | Create a new pthread_attr_tstructure and use the pthread_attr_setstacksizefunction to change the default stack size. Pass the attributes to the pthread_createfunction when creating your thread. |
Multiprocessing Services | Pass the appropriate stack size value to the MPCreateTaskfunction when you create your thread. |
需要分配空间,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 NSThreadobject (do not use the detachNewThreadSelector:toTarget:withObject:method). Before calling the startmethod of the thread object, use the setStackSize:method to specify the new stack size. |
POSIX | Create a new pthread_attr_tstructure and use the pthread_attr_setstacksizefunction to change the default stack size. Pass the attributes to the pthread_createfunction when creating your thread. |
For Cocoa threads, you can use the
setThreadPriority:class method of
NSThreadto set the priority of the currently running thread. For POSIX threads, you use the
pthread_setschedparamfunction. For more information, see NSThread Class Reference or
pthread_setschedparamman page.
线程中的全局变量
可以在线程中任何地方访问
threadDictionarymethod of an
NSThreadobject to retrieve an
NSMutableDictionaryobject, to which you can add any keys required by your thread.
In POSIX, you use the
pthread_setspecificand
pthread_getspecificfunctions 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,因此问题就解决了。
相关文章推荐
- [IOS笔记] - 关于线程[3]
- [IOS笔记] - 关于线程[2]
- 黑马程序员-IOS学习笔记 OC 关于匿名类相关概念
- 关于xib的一些简单用法(ios自学笔记)
- 黑马程序员--关于线程的一些笔记总结
- ios学习笔记(七)关于NSUInteger
- iOS 关于dispatch_semaphore_t(信号量) 和 dispatch_group_t (组) 线程执行顺序的使用
- ios开发笔记--关于delegate(委托)的使用心得
- 笔记-关于线程
- 关于iOS学习笔记(1)
- iOS开发笔记--关于 @synchronized,这儿比你想知道的还要多
- iOS 开发笔记(线程)
- IOS学习笔记64--关于linker command failed with exit code错误
- iOS学习笔记-134.RunLoop02——Runloop与线程
- 关于iOS的UIView的一点笔记
- ios开发笔记--关于delegate(委托)的使用心得
- iOS开发笔记--关于 setBackgroundImage 和 setImage
- ios 关于时间戳与时间转化的笔记
- IOS 学习笔记--关于对Block的理解
- IOS开发笔记之二十二——关于导航栏与状态栏的操作总结