【转】iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

转自容芳志的博客

简介

iOS有三种多线程编程的技术,分别是:

(一)NSThread

(二)Cocoa NSOperation

(三)GCD(全称:Grand Central Dispatch)

这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。

三种方式的优缺点介绍:

1)NSThread:

优点:NSThread 比其他两个轻量级

缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销

NSThread实现的技术有下面三种:

一般使用cocoa thread 技术。

Cocoa NSOperation

优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。

NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。

GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。现在的iOS系统都升级到7了,所以不用担心该技术不能使用。

介绍完这三种多线程编程方式,本文将依次介绍这三种技术的使用。

(一)NSThread的使用

NSThread 有两种直接创建方式:

  1. - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
  2. + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

第一个是实例方法,第二个是类方法

  1. 1、[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
  2. 2、NSThread* myThread = [[NSThread alloc] initWithTarget:self
  3. selector:@selector(doSomething:)
  4. object:nil];
  5. [myThread start];

参数的意义:

selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。

target  :selector消息发送的对象

argument:传输给target的唯一参数,也可以是nil

第一种方式会直接创建线程并且开始运行线程,第二种方式是先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息

不显式创建线程的方法:

用NSObject的类方法  performSelectorInBackground:withObject: 创建一个线程:

  1. [Obj performSelectorInBackground:@selector(doSomething) withObject:nil];

下载图片的例子:

新建singeView app

新建项目,并在xib文件上放置一个imageView控件。按住control键拖到viewController.h文件中创建imageView IBOutlet ViewController.m中实现:

  1. //
  2. //  ViewController.m
  3. //  NSThreadDemo
  4. //
  5. //  Created by rongfzh on 12-9-23.
  6. //  Copyright (c) 2012年 rongfzh. All rights reserved.
  7. //
  8. #import "ViewController.h"
  9. #define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"
  10. @interface ViewController ()
  11. @end
  12. @implementation ViewController
  13. -(void)downloadImage:(NSString *) url{
  14. NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
  15. UIImage *image = [[UIImage alloc]initWithData:data];
  16. if(image == nil){
  17. }else{
  18. [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
  19. }
  20. }
  21. -(void)updateUI:(UIImage*) image{
  22. self.imageView.image = image;
  23. }
  24. - (void)viewDidLoad
  25. {
  26. [super viewDidLoad];
  27. //    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
  28. NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
  29. [thread start];
  30. }
  31. - (void)didReceiveMemoryWarning
  32. {
  33. [super didReceiveMemoryWarning];
  34. // Dispose of any resources that can be recreated.
  35. }
  36. @end

线程间通讯

线程下载完图片后怎么通知主线程更新界面呢?

  1. [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];

performSelectorOnMainThread是NSObject的方法,除了可以更新主线程的数据外,还可以更新其他线程的比如:

  1. performSelector:onThread:withObject:waitUntilDone:

运行下载图片:

线程同步

我们演示一个经典的卖票的例子来讲NSThread的线程同步:

  1. #import <UIKit/UIKit.h>
  2. @class ViewController;
  3. @interface AppDelegate : UIResponder <UIApplicationDelegate>
  4. {
  5. int tickets;
  6. int count;
  7. NSThread* ticketsThreadone;
  8. NSThread* ticketsThreadtwo;
  9. NSCondition* ticketsCondition;
  10. NSLock *theLock;
  11. }
  12. @property (strong, nonatomic) UIWindow *window;
  13. @property (strong, nonatomic) ViewController *viewController;
  14. @end
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3. tickets = 100;
  4. count = 0;
  5. theLock = [[NSLock alloc] init];
  6. // 锁对象
  7. ticketsCondition = [[NSCondition alloc] init];
  8. ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
  9. [ticketsThreadone setName:@"Thread-1"];
  10. [ticketsThreadone start];
  11. ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
  12. [ticketsThreadtwo setName:@"Thread-2"];
  13. [ticketsThreadtwo start];
  14. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  15. // Override point for customization after application launch.
  16. self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
  17. self.window.rootViewController = self.viewController;
  18. [self.window makeKeyAndVisible];
  19. return YES;
  20. }
  21. - (void)run{
  22. while (TRUE) {
  23. // 上锁
  24. //        [ticketsCondition lock];
  25. [theLock lock];
  26. if(tickets >= 0){
  27. [NSThread sleepForTimeInterval:0.09];
  28. count = 100 - tickets;
  29. NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
  30. tickets--;
  31. }else{
  32. break;
  33. }
  34. [theLock unlock];
  35. //        [ticketsCondition unlock];
  36. }
  37. }

如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。

上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。

线程的顺序执行

他们都可以通过[ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。

比如:

  1. #import "AppDelegate.h"
  2. #import "ViewController.h"
  3. @implementation AppDelegate
  4. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  5. {
  6. tickets = 100;
  7. count = 0;
  8. theLock = [[NSLock alloc] init];
  9. // 锁对象
  10. ticketsCondition = [[NSCondition alloc] init];
  11. ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
  12. [ticketsThreadone setName:@"Thread-1"];
  13. [ticketsThreadone start];
  14. ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
  15. [ticketsThreadtwo setName:@"Thread-2"];
  16. [ticketsThreadtwo start];
  17. NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];
  18. [ticketsThreadthree setName:@"Thread-3"];
  19. [ticketsThreadthree start];
  20. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  21. // Override point for customization after application launch.
  22. self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
  23. self.window.rootViewController = self.viewController;
  24. [self.window makeKeyAndVisible];
  25. return YES;
  26. }
  27. -(void)run3{
  28. while (YES) {
  29. [ticketsCondition lock];
  30. [NSThread sleepForTimeInterval:3];
  31. [ticketsCondition signal];
  32. [ticketsCondition unlock];
  33. }
  34. }
  35. - (void)run{
  36. while (TRUE) {
  37. // 上锁
  38. [ticketsCondition lock];
  39. [ticketsCondition wait];
  40. [theLock lock];
  41. if(tickets >= 0){
  42. [NSThread sleepForTimeInterval:0.09];
  43. count = 100 - tickets;
  44. NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
  45. tickets--;
  46. }else{
  47. break;
  48. }
  49. [theLock unlock];
  50. [ticketsCondition unlock];
  51. }
  52. }

wait是等待,我加了一个 线程3 去唤醒其他两个线程锁中的wait

其他同步

我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。

  1. - (void)doSomeThing:(id)anObj
  2. {
  3. @synchronized(anObj)
  4. {
  5. // Everything between the braces is protected by the @synchronized directive.
  6. }
  7. }

还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,可以自己看官方文档学习

NSThread下载图片的例子代码:http://download.csdn.net/detail/totogo2010/4591149

(二)Cocoa NSOperation的使用

使用 NSOperation的方式有两种,

一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

另一种是继承NSOperation

如果你也熟悉Java,NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。

NSInvocationOperation例子:

这里同样,我们实现一个下载图片的例子。新建一个Single View app,拖放一个ImageView控件到xib界面。

实现代码如下:

  1. #import "ViewController.h"
  2. #define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"
  3. @interface ViewController ()
  4. @end
  5. @implementation ViewController
  6. - (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self
  10. selector:@selector(downloadImage:)
  11. object:kURL];
  12. NSOperationQueue *queue = [[NSOperationQueue alloc]init];
  13. [queue addOperation:operation];
  14. // Do any additional setup after loading the view, typically from a nib.
  15. }
  16. -(void)downloadImage:(NSString *)url{
  17. NSLog(@"url:%@", url);
  18. NSURL *nsUrl = [NSURL URLWithString:url];
  19. NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];
  20. UIImage * image = [[UIImage alloc]initWithData:data];
  21. [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
  22. }
  23. -(void)updateUI:(UIImage*) image{
  24. self.imageView.image = image;
  25. }

代码注释:

1.viewDidLoad方法里可以看到我们用NSInvocationOperation建了一个后台线程,并且放到2.NSOperationQueue中。后台线程执行downloadImage方法。

3.downloadImage 方法处理下载图片的逻辑。下载完成后用performSelectorOnMainThread执行主线程updateUI方法。

updateUI 并把下载的图片显示到图片控件中。

运行可以看到下载图片显示在界面上。

第二种方式继承NSOperation 

在.m文件中实现main方法,main方法编写要执行的代码即可。

如何控制线程池中的线程数?

队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。

通过下面的代码设置:

  1. [queue setMaxConcurrentOperationCount:5];

线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作。

(三)GCD的介绍和使用

介绍:

Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。

设计:

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。

dispatch queue分为下面三种:

Serial

又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

Concurrent

又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。

Main dispatch queue

它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

我们看看dispatch queue如何使用?

1、常用的方法dispatch_async

为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

用GCD实现这个流程的操作比前面介绍的NSThread  NSOperation的方法都要简单。代码框架结构如下:

  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  2. // 耗时的操作
  3. dispatch_async(dispatch_get_main_queue(), ^{
  4. // 更新界面
  5. });
  6. });

如果这样还不清晰的话,那我们还是用上两篇博客中的下载图片为例子,代码如下:

  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  2. NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];
  3. NSData * data = [[NSData alloc]initWithContentsOfURL:url];
  4. UIImage *image = [[UIImage alloc]initWithData:data];
  5. if (data != nil) {
  6. dispatch_async(dispatch_get_main_queue(), ^{
  7. self.imageView.image = image;
  8. });
  9. }
  10. });

运行显示:

是不是代码比NSThread  NSOperation简洁很多,而且GCD会自动根据任务在多核处理器上分配资源,优化程序。

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:

  1. dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

这里也用到了系统默认就有一个串行队列main_queue:

  1. dispatch_queue_t mainQ = dispatch_get_main_queue();

虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。

2、dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  2. dispatch_group_t group = dispatch_group_create();
  3. dispatch_group_async(group, queue, ^{
  4. [NSThread sleepForTimeInterval:1];
  5. NSLog(@"group1");
  6. });
  7. dispatch_group_async(group, queue, ^{
  8. [NSThread sleepForTimeInterval:2];
  9. NSLog(@"group2");
  10. });
  11. dispatch_group_async(group, queue, ^{
  12. [NSThread sleepForTimeInterval:3];
  13. NSLog(@"group3");
  14. });
  15. dispatch_group_notify(group, dispatch_get_main_queue(), ^{
  16. NSLog(@"updateUi");
  17. });
  18. dispatch_release(group);

dispatch_group_async是异步的方法,运行后可以看到打印结果:

  1. 2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
  2. 2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
  3. 2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
  4. 2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

每个一秒打印一个,当第三个任务执行后,upadteUi被打印。

3、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

例子代码如下:

  1. dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
  2. dispatch_async(queue, ^{
  3. [NSThread sleepForTimeInterval:2];
  4. NSLog(@"dispatch_async1");
  5. });
  6. dispatch_async(queue, ^{
  7. [NSThread sleepForTimeInterval:4];
  8. NSLog(@"dispatch_async2");
  9. });
  10. dispatch_barrier_async(queue, ^{
  11. NSLog(@"dispatch_barrier_async");
  12. [NSThread sleepForTimeInterval:4];
  13. });
  14. dispatch_async(queue, ^{
  15. [NSThread sleepForTimeInterval:1];
  16. NSLog(@"dispatch_async3");
  17. });

打印结果:

  1. 2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1
  2. 2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2
  3. 2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async
  4. 2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

请注意执行的时间,可以看到执行的顺序如上所述。

4、dispatch_apply 

执行某个代码片段N次。

  1. dispatch_apply(5, globalQ, ^(size_t index) {
  2. // 执行5次
  3. });

本篇使用的到的例子代码:http://download.csdn.net/detail/totogo2010/4596471

GCD还有很多其他用法,可以参考官方文档http://en.wikipedia.org/wiki/Grand_Central_Dispatch

扩展阅读:

GCD 深入理解(一)

GCD 深入理解(二)

时间: 2024-11-03 21:56:18

【转】iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD的相关文章

iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

简介iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍:1)NSThread:优点:NSThread 比其他两个轻量级缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术有下面三种:一般使用cocoa

iOS多线程编程

1. 进程,线程, 任务 进程:一个程序在运行时,系统会为其分配一个进程,用以管理他的一些资源. 线程:进程内所包含的一个或多个执行单元称为线程,线程一般情况下不持有资源,但可以使用其所在进程的资源. 任务:进程或线程中要做的事情. 在引入线程的操作系统中,通常把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位. 线程比进程更小,对其调度的开销小,能够提高系统内多个任务的并发执行程度. 一个程序至少有一个进程,一个进程至少有一个线程.一个程序就是一个进程,而一个程序中的多个任

IOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

前言:在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间和资源)等等.也就是说,我们可以使用线程把占据时间长的任务放到后台中处理,而不影响到用户的使用. 线程的定义: 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理

iOS多线程编程Part 1/3 - NSThread &amp; Run Loop

iOS多线程编程Part 1/3 - NSThread & Run Loop 02 JUNE 2013 前言 多线程的价值无需赘述,对于App性能和用户体验都有着至关重要的意义,在iOS开发中,Apple提供了不同的技术支持多线程编程,除了跨平台的pthread之外,还提供了NSThread.NSOperationQueue.GCD等多线程技术,从本篇Blog开始介绍这几种多线程技术的细节. 对于pthread这种跨平台的多线程技术,这本Programming with POSIX Thread

iOS并发编程对比总结,NSThread,NSOperation,GCD - iOS

1. 多线程概念 进程 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行 1.1 多任务系统调度示意图 说明:每个应用程序由操作系统分配的短暂的时间片(Timeslice)轮流使用CPU,由于CPU对每个时间片的处理速度非常快

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

iOS多线程编程(四)------ GCD(Grand Central Dispatch)

一.简介 是基于C语言开发的一套多线程开发机制,也是目前苹果官方推荐的多线程开发方法,用起来也最简单,只是它基于C语言开发,并不像NSOperation是面向对象的开发,而是完全面向过程的.如果使用GCD,完全由系统管理线程,我们不需要编写线程代码.只需定义想要执行的任务,然后添加到适当的调度队列(dispatch_queue).GCD会负责创建线程和调度你的任务,系统会直接提供线程管理. 二.任务和队列 GCD中有两个核心概念 (1)任务:执行什么操作 (2)队列:用来存放任务 GCD的使用就

3.IOS多线程编程的总结帖

转载请在开头注明出处: 刘锐的博客 http://www.cnblogs.com/rui-liu/p/4488645.html 面试的时候,多线程的东西总是被问到,或深或浅,如果是BAT,问的特别深,有很多追加问题,两三个追加就能探到你的底,想想真恐怖??.很多东西了解,知道,用的不多,容易忘,所以总结一下关于多线程的各种高质量帖,以备不时之需. 1. GCD深入理解:第一部分 https://github.com/nixzhu/dev-blog/blob/master/2014-04-19-g

多线程编程技术基础知识

GPS平台.网站建设.软件开发.系统运维,找森大网络科技!http://cnsendnet.taobao.com来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=414 多线程编程技术基础知识 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同