IOS多线程及队列的使用

IOS多线程及队列的使用

分类: ios多线程2013-12-11 17:56 1898人阅读 评论(0) 收藏 举报

多线程

最近搞一款塔防游戏,提到塔防,自然就想到了A星寻路。的确,它是一种高效的寻路算法。但当很多怪物同时在调用A星算法来寻找一条最近的路径来到达目的地时,我发现会很卡。我都不能接受这个卡屏,更何况是玩家呢。
所有我一直都在努力去优化A星算法。虽然有所改善,但卡的问题还是存在。
实在没辙了,我想到了队列线程。之前都没接触过这个东东,还好在网上找到很详细的线程介绍。当然,我只是用到了其中的一点点。分享给大家,希望有所帮助。

原文链接:http://www.uml.org.cn/mobiledev/201210262.asp

目录:

IOS多线程编程之NSThread的使用

IOS多线程编程之NSOperation和NSOperationQueue的使用

IOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

IOS多线程编程之NSThread的使用

1、简介:

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

1.、NSThread

2、Cocoa NSOperation (IOS多线程编程之NSOperation和NSOperationQueue的使用)

3、GCD 全称:Grand Central Dispatch( IOS多线程编程之Grand Central Dispatch(GCD)介绍和使用)

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

这篇我们主要介绍和使用NSThread,后面会继续2、3 的讲解和使用。

1.2 三种方式的有缺点介绍:

NSThread:

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

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

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

Technology Description
Cocoa threads Cocoa implements threads using the NSThread class. Cocoa also provides methods on NSObject for spawning new threads and executing code on already-running threads. For more information, see “Using NSThread” and “Using NSObject to Spawn a Thread.”
POSIX threads POSIX threads provide a C-based interface for creating threads. If you are not writing a Cocoa application, this is the best choice for creating threads. The POSIX interface is relatively simple to use and offers ample flexibility for configuring your threads. For more information, see “Using POSIX Threads”
Multiprocessing Services Multiprocessing Services is a legacy C-based interface used by applications transitioning from older versions of Mac OS. This technology is available in OS X only and should be avoided for any new development. Instead, you should use the NSThread class or POSIX threads. If you need more information on this technology, see Multiprocessing Services Programming Guide.

一般使用cocoa thread 技术。
Cocoa operation
优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。
Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。
GCD
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。现在的IOS系统都升级到6了,所以不用担心该技术不能使用。
介绍完这三种多线程编程方式,我们这篇先介绍NSThread的使用。
2、NSThread的使用
2.1 NSThread 有两种直接创建方式:
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
第一个是实例方法,第二个是类方法

复制代码

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

2.2参数的意义:
selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
target :selector消息发送的对象
argument:传输给target的唯一参数,也可以是nil
第一种方式会直接创建线程并且开始运行线程,第二种方式是先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
2.3 PS:不显式创建线程的方法:
用NSObject的类方法 performSelectorInBackground:withObject: 创建一个线程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
2.4 下载图片的例子:
2.4.1 新建singeView app
新建项目,并在xib文件上放置一个imageView控件。按住control键拖到viewControll
er.h文件中创建imageView IBOutlet
ViewController.m中实现:

复制代码

  1. //
    //  ViewController.m
    //  NSThreadDemo
    //
    //  Created by rongfzh on 12-9-23.
    //  Copyright (c) 2012年 rongfzh. All rights reserved.
    //

    #import "ViewController.h"
    #define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"
    @interface ViewController ()

    @end

    @implementation ViewController

    -(void)downloadImage:(NSString *) url{
        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
        UIImage *image = [[UIImage alloc]initWithData:data];
        if(image == nil){

    }else{
            [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
        }
    }

    -(void)updateUI:(UIImage*) image{
        self.imageView.image = image;
    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];

    //    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
        NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
        [thread start];
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    @end

2.4.2线程间通讯
线程下载完图片后怎么通知主线程更新界面呢?
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
performSelectorOnMainThread是NSObject的方法,除了可以更新主线程的数据外,还可以更新其他线程的比如:
用:performSelector:onThread:withObject:waitUntilDone:

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

复制代码

  1. #import <UIKit/UIKit.h>
    @class ViewController;
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    {
        int tickets;
        int count;
        NSThread* ticketsThreadone;
        NSThread* ticketsThreadtwo;
        NSCondition* ticketsCondition;
        NSLock *theLock;
    }
    @property (strong, nonatomic) UIWindow *window;
    @property (strong, nonatomic) ViewController *viewController;
    @end

复制代码

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {

    tickets = 100;
        count = 0;
        theLock = [[NSLock alloc] init];
        // 锁对象
        ticketsCondition = [[NSCondition alloc] init];
        ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        [ticketsThreadone setName:@"Thread-1"];
        [ticketsThreadone start];

    ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        [ticketsThreadtwo setName:@"Thread-2"];
        [ticketsThreadtwo start];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
        self.window.rootViewController = self.viewController;
        [self.window makeKeyAndVisible];
        return YES;
    }

    - (void)run{
        while (TRUE) {
            // 上锁
    //        [ticketsCondition lock];
            [theLock lock];
            if(tickets >= 0){
                [NSThread sleepForTimeInterval:0.09];
                count = 100 - tickets;
                NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
                tickets--;
            }else{
                break;
            }
            [theLock unlock];
    //        [ticketsCondition unlock];
        }
    }

如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。
上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。
线程的顺序执行
他们都可以通过
[ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。
比如:

复制代码

  1. #import "AppDelegate.h"

    #import "ViewController.h"

    @implementation AppDelegate

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {

    tickets = 100;
        count = 0;
        theLock = [[NSLock alloc] init];
        // 锁对象
        ticketsCondition = [[NSCondition alloc] init];
        ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        [ticketsThreadone setName:@"Thread-1"];
        [ticketsThreadone start];

    ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        [ticketsThreadtwo setName:@"Thread-2"];
        [ticketsThreadtwo start];

    NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];
        [ticketsThreadthree setName:@"Thread-3"];
        [ticketsThreadthree start];    
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
        self.window.rootViewController = self.viewController;
        [self.window makeKeyAndVisible];
        return YES;
    }

    -(void)run3{
        while (YES) {
            [ticketsCondition lock];
            [NSThread sleepForTimeInterval:3];
            [ticketsCondition signal];
            [ticketsCondition unlock];
        }
    }

    - (void)run{
        while (TRUE) {
            // 上锁
            [ticketsCondition lock];
            [ticketsCondition wait];
            [theLock lock];
            if(tickets >= 0){
                [NSThread sleepForTimeInterval:0.09];
                count = 100 - tickets;
                NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
                tickets--;
            }else{
                break;
            }
            [theLock unlock];
            [ticketsCondition unlock];
        }
    }

wait是等待,我加了一个 线程3 去唤醒其他两个线程锁中的wait
其他同步
我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
- (void)doSomeThing:(id)anObj
{
@synchronized(anObj)
{
// Everything between the braces is protected by the @synchronized directive.
}
}
还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,可以自己看官方文档学习NSThread下载图片的例子代码:http://download.csdn.net/detail/totogo2010/4591149
IOS多线程编程之NSOperation和NSOperationQueue的使用
前一篇 IOS多线程编程之NSThread的使用介绍三种多线程编程和NSThread的使用,这篇介绍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"
    #define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"@interface ViewController ()@[email protected] ViewController- (void)viewDidLoad{    [super viewDidLoad];    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self                                                                           selector:@selector(downloadImage:)                                                                             object:kURL];        NSOperationQueue *queue = [[NSOperationQueue alloc]init];    [queue addOperation:operation];    // Do any additional setup after loading the view, typically from a nib.}-(void)downloadImage:(NSString *)url{    NSLog(@"url:%@", url);    NSURL *nsUrl = [NSURL URLWithString:url];    NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];    UIImage * image = [[UIImage alloc]initWithData:data];    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];}-(void)updateUI:(UIImage*) image{    self.imageView.image = image; }

1.viewDidLoad方法里可以看到我们用NSInvocationOperation建了一个后台线程,并且放到NSOperationQueue中。后台线程执行downloadImage方法。
2.downloadImage 方法处理下载图片的逻辑。下载完成后用performSelectorOnMainThread执行主线程updateUI方法。
3.updateUI 并把下载的图片显示到图片控件中。

第二种方式继承NSOperation
在.m文件中实现main方法,main方法编写要执行的代码即可。
如何控制线程池中的线程数?
队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。
通过下面的代码设置:
[queue setMaxConcurrentOperationCount:5];线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作。
IOS多线程编程之Grand Central Dispatch(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), ^{
        // 耗时的操作
        dispatch_async(dispatch_get_main_queue(), ^{
            // 更新界面
        });
    });

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

复制代码

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

是不是代码比NSThread NSOperation简洁很多,而且GCD会自动根据任务在多核处理器上分配资源,优化程序。
系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

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

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);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
            [NSThread sleepForTimeInterval:1];
            NSLog(@"group1");
        });
        dispatch_group_async(group, queue, ^{
            [NSThread sleepForTimeInterval:2];
            NSLog(@"group2");
        });
        dispatch_group_async(group, queue, ^{
            [NSThread sleepForTimeInterval:3];
            NSLog(@"group3");
        });
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"updateUi");
        });
        dispatch_release(group);

dispatch_group_async是异步的方法,运行后可以看到打印结果:
2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
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);
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:2];
            NSLog(@"dispatch_async1");
        });
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:4];
            NSLog(@"dispatch_async2");
        });
        dispatch_barrier_async(queue, ^{
            NSLog(@"dispatch_barrier_async");
            [NSThread sleepForTimeInterval:4];

    });
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:1];
            NSLog(@"dispatch_async3");
        });

打印结果:
2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async
2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3
请注意执行的时间,可以看到执行的顺序如上所述。
4、dispatch_apply
执行某个代码片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
// 执行5次
});

时间: 2024-10-20 12:52:41

IOS多线程及队列的使用的相关文章

iOS多线程开发小demo7 GCD队列组

// DYFViewController.m // 623-08-队列组 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @property (weak, nonatomic) IBOutlet UIImageVi

iOS多线程 GCD

iOS多线程 GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispatch_get_main_queue获取. /*! * @function dispatch_get_main_queue * * @abstract * Returns the default queue that is bound to the main thread. *

iOS多线程编程

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

关于iOS多线程的总结

关于iOS多线程的总结 在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项.当然也会给出几种多线程的案例,在实际使用中感受它们的区别.还有一点需要说明的是,这篇文章将会使用 Swift 和 Objective-c 两种语言讲解,双语幼儿园.OK,let's begin! 概述 这篇文章中,我不会说多线程是什么.线程和进程的区别.多线程有什么用,当然我也不会说什么是串行.什么是并行等问题,这些我们应该都知道的. 在 iOS 中其实目前有 4 套多线程方案,他们分

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

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

iOS 多线程详解

iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作: 对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程中继续执行,用户同样可以继续进行其他UI操作,与此同时前一个操作的后续任务可以分散到多个空闲CPU中继续执行(当然具体调度顺序要根据

iOS多线程GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispatch_get_main_queue获取. /*! * @function dispatch_get_main_queue * * @abstract * Returns the default queue that is bound to the main thread. * * @discussi

iOS多线程自定义operation加载图片 不重复下载图片

摘要:1:ios通过抽象类NSOperation封装了gcd,让ios的多线程变得更为简单易用:   2:耗时的操作交给子线程来完成,主线程负责ui的处理,提示用户的体验   2:自定义operation继承自NSOperation,在子线程中下载图片: 3:保证图片只下载一次,还有保证下载任务不重复 ------------------------------------------------------------------------------------ 实现原理:1:图片缓存:用

iOS多线程与网络开发之多线程概述

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 如果文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额随意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源码下载:点我传送 游戏官方下载:http://dwz.cn/RwTjl 游戏视频预览:http://dwz.cn/RzHHd 游戏开发博客:http://dwz.cn/RzJzI 游戏源码传送:http://dwz.cn/Nret1 A.进程 什么是进程进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行