- IOS multithreading, spin locks and mutex details
- NSThread for iOS multithreading
- NSOperation for iOS multithreading
- IOS Multithreading GCD
preface
NSThread is apple’s official object-oriented thread operation technology. It is simple and convenient. You can directly operate thread objects, but you need to control the life cycle of the thread. [NSThread currentThread] [NSThread currentThread]
1 NSThread briefly
Apple Official Documents
- a
NSThread
The object represents a thread NSThread
The function is automatically recalled after executing the task
2 NSThread create
- Dynamically create
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(threadFunction1: object:@" initialize: thread"]; NSThread = [[NSThread alloc] initWithBlock:^{NSLog(@" init: thread2");}]; NSThread *thread3 = [[NSThread alloc] init];Copy the code
Thread1, thread2, thread3 need to be started by calling start
- The static create
// Since the static method does not return a value, if you want to get the newly created thread, you need to call the method that gets the current thread in the selector [NSThread detachNewThreadSelector:@selector(threadFunction2:) ToTarget :self withObject:@" static create "];Copy the code
3 NSThread method
- Start and Cancel
// thread start [thread1 start]; // Thread cancels [thread cancel];Copy the code
- Thread to stop
The thread stop method immediately terminates all threads except the main thread (whether or not they are executing a task) and exits. This method needs to be invoked while controlling the state of all threads, otherwise it may cause memory problems and cannot be restarted once stopped
[NSThread exit];
Copy the code
- Thread method
// is the main thread [NSThread isMainThread]; // set the mainThread to [NSThread mainThread]; // get the currentThread [NSThread currentThread]; / / set the thread priority [NSThread currentThread]. QualityOfService = NSQualityOfServiceBackground; // Thread pause [NSThread sleepForTimeInterval:1.0]; [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]].Copy the code
4 Communication methods between threads
- Specifies the current thread of execution
[self performSelector:@selector(threadFunction)]; [self performSelector:@selector(threadFunction) withObject:nil]; [the self performSelector: @ the selector (threadFunction) withObject: nil afterDelay: 2.0];Copy the code
- Other threads specify the main thread to execute
[self performSelectorOnMainThread:@selector(threadFunction) withObject:nil waitUntilDone:YES];
Copy the code
- Specify other threads in the main thread to perform operations
// this is specified for a thread [self performSelector:@selector(threadFunction) onThread:newThread withObject:nil waitUntilDone:YES]; / / here is specified as a background thread [self performSelectorInBackground: @ the selector (threadFunction) withObject: nil];Copy the code
- Thread synchronization
Threads may share some resources with other threads, which may cause conflicts when multiple threads read and write the same shared resource. Thread synchronization means that only one thread is allowed to access a resource at a certain time
IOS thread locking is implemented in two ways: NSLock and @synchronized
Advantages: It effectively prevents data security problems caused by multi-threaded resource grabs. Disadvantages: It consumes a large amount of CPU resources
5. Use of NSThread: simulate ticket selling
Scenario: tickets of A cinema are on sale, and Windows are opened in window A and window B for sales. The following is the code implementation
{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExit) name:NSThreadWillExitNotification object:nil]; Self. ticketsCount = 20; NSThread *windowA = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; Windowa. name = @" windowa. name "; [windowA start]; NSThread *windowB = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; Windowb. name = @" windowB "; [windowB start]; } // saleTicket - (void)saleTicket {// If the thread starts, saleTicket will be executed. While (1) {// Add the mutex if (self.ticketsCount > 0) {self.ticketsCount--; NSLog(@"%@, %ld", [NSThread currentThread].name, (long)self.ticketsCount); [NSThread sleepForTimeInterval: 0.2]; } else { break; }} - (void)threadExit {NSLog(@" threadExit "); }Copy the code
Execution Result:
Window A, 12 window A, 11 window B, 10 window B, 8 window A, 8 window B, 7 window A, 6 window B, 5 window A, 4 window B, 3 window A, 2 window B, 0 Window A, 1Copy the code
In the process of ticket selling, multiple threads access the same resource, resulting in quantity disorder. In the process of ticket selling, we add mutex to the ticket. Only one thread can operate on the number of tickets at a time, and when the operation is complete, other threads can continue to operate on the number of tickets.
@synchronized(self)
Add a mutex
- (void)saleTicket {// After the thread starts, saleTicket is executed, and then the thread exits. While (1) {synchronized(self) {if (self.ticketsCount > 0) {self.ticketscount --; NSLog(@"%@, %ld", [NSThread currentThread].name, (long)self.ticketsCount); [NSThread sleepForTimeInterval: 0.2]; } else { break; }}} // the thread exits.Copy the code
Print result:
Window B, 6 window B, 5 window A, 4 window A, 2 window B, 3 window B, 1 window A, 1 window B, 0Copy the code
Set the thread to always run, custom cancel
{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExit) name:NSThreadWillExitNotification object:nil]; Self. ticketsCount = 20; NSThread *windowA = [[NSThread alloc] initWithTarget:self selector:@selector(threadWindowA) object:nil]; Windowa. name = @" windowa. name "; [windowA start]; NSThread *windowB = [[NSThread alloc] initWithTarget:self selector:@selector(threadWindowB) object:nil]; Windowb. name = @" windowB "; [windowB start]; [self performSelector:@selector(saleTicket) onThread:windowA withObject:nil waitUntilDone:NO]; [self performSelector:@selector(saleTicket) onThread:windowB withObject:nil waitUntilDone:NO]; } - (void)threadWindowA { NSRunLoop *runLoop1 = [NSRunLoop currentRunLoop]; // Run [runLoop1 runUntilDate:[NSDate date]]; } - (void)threadWindowB { NSRunLoop *runLoop2 = [NSRunLoop currentRunLoop]; / / custom runtime [runLoop2 runMode: NSDefaultRunLoopMode beforeDate: [NSDate dateWithTimeIntervalSinceNow: 12.0]]. } // saleTicket - (void)saleTicket {// If the thread starts, saleTicket will be executed. While (1) {// Add the mutex if (self.ticketsCount > 0) {self.ticketsCount--; NSLog(@"%@, %ld", [NSThread currentThread].name, (long)self.ticketsCount); [NSThread sleepForTimeInterval: 0.2]; } else {if ([NSThread currentThread]. IsCancelled) {break; } else {NSLog(@" sold out "); [NSThread currentThread] cancel]; [NSThread currentThread] cancel]; // Stop the current thread runLoop CFRunLoopStop(CFRunLoopGetCurrent()); }}}} - (void)threadExit {NSLog(@" threadExit :%@", [NSThread currentThread].name); }Copy the code
See GitHub-> Multithreading for the full code
If there are shortcomings, welcome to correct, if you feel good writing, remember to give a thumbs up!