并行程序设计 中文课件 04 Windows多线程程序设计_第1页
并行程序设计 中文课件 04 Windows多线程程序设计_第2页
并行程序设计 中文课件 04 Windows多线程程序设计_第3页
并行程序设计 中文课件 04 Windows多线程程序设计_第4页
并行程序设计 中文课件 04 Windows多线程程序设计_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ParallelProgrammingInstructor:ZhangWeizhe(张伟哲)ComputerNetworkandInformationSecurityTechniqueResearchCenter,SchoolofComputerScienceandTechnology,HarbinInstituteofTechnologyProgrammingSharedAddressSpacePlatforms

编程共享地址空间平台1.进程的引入

多个程序在执行时,需要共享系统资源,从而导致各程序在执行过程中出现相互制约的关系,程序的执行表现出间断性的特征。 这些特征都是在程序的执行过程中发生的,是动态的过程,而传统的程序本身是一组指令的集合,是一个静态的概念,无法描述程序在内存中的执行情况,即我们无法从程序的字面上看出它何时执行,何时停顿,也无法看出它与其它执行程序的关系,因此,程序这个静态概念已不能如实反映程序并发执行过程的特征。为了深刻描述程序动态执行过程的性质,人们引入“进程(Process)”概念。

进程(Process)进程(Process)进程的概念是60年代初首先由麻省理工学院的MULTICS系统和IBM公司的CTSS/360系统引入的。进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。进程是操作系统中最基本、重要的概念。是多任务程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。进程(process)离散的(执行)程序任务集合。一个进程包括:进程ID,进程组ID,用户ID,组ID;环境工作目录程序指令寄存器堆栈(Stack)堆(Heap)文件描述符信号操作共享库进程间通信工具消息队列、管道、信号量、共享内存UNIX下进程示例进程(Process)概念进程的特征动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的。并发性:任何进程都可以同其他进程一起并发执行独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进

结构特征:进程由程序、数据和进程控制块三部分组成。

进程(Process)与程序进程为应用程序的运行实例,是应用程序的一次动态执行。我们可以简单地理解为:它是操作系统当前运行的执行程序。对应用程序来说,进程就像一个大容器。在应用程序被运行后,就相当于将应用程序装进容器里了,你可以往容器里加其他东西(如:应用程序在运行时所需的变量数据、需要引用的DLL文件等),当应用程序被运行两次时,容器里的东西并不会被倒掉,系统会找一个新的进程容器来容纳它。进程与程序的关系程序是指令的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念。

(1)程序可以作为一种软件资料长期存在,而进程是有一定生命期的。程序是永久的,进程是暂时的。

(2)进程更能真实地描述并发,而程序不能;进程是由程序和数据两部分组成的。

(3)进程具有创建其他进程的功能,而程序没有。

(4)同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程。也就是说同一程序可以对应多个进程。

(5)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单元都是进程。WhyThreads?发挥软件作用充分利用系统(CPU)资源,提高使用效率多线程的概念线程(thread)是进程上下文(context)中执行的代码序列,是进程中的一个实体,是被系统独立调度和分派的基本单位,又被称为轻量级进程(lightweightprocess)在支持多线程的系统中,进程成为资源分配和保护的实体,而线程是被调度执行的基本单元。线程只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。一个进程内的线程示例一个线程对共享的系统资源进行修改,在这个进程内的其它线程也可以见到这种修改。对于同一个数据,可能有两个值相同的指针指向这个数据。进程内的多个线程可以对同一个内存单元进行读和写操作,所以必须要采取显式同步机制。在同一个进程的地址空间下,线程间的通信消耗更小。对于在一个进程内的线程:进程与线程的关系程序在操作系统中作为进程方式存在、获取资源、运行。在一个进程内,线程可以创建其它线程。每个线程有各自的栈(stack)。一个进程内所有的线程共享代码段和数据段。进程进程与线程的关系线程和进程的区别在于:子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定.线程的运行中需要使用计算机的内存资源和CPU

多核与线程并行的关系在单核平台上的线程并发:在各个核上可以实现线程并行:CPU核核1核2多线程的优点创建一个线程比创建一个进程的代价要小线程的切换比进程间的切换代价小充分利用多处理器数据共享数据共享使得线程之间的通信比进程间的通信更高效快速响应特性在系统繁忙的情况下,进程通过独立的线程及时响应用户的输入线程的层次用户级线程(User-levelthreads)在应用软件中所创建和操纵的线程。内核级线程(Kernel-levelthreads)操作系统实现大多数线程的方式。硬件线程(Hardwarethreads)

线程在硬件资源上的表现形式。用户级线程用户级线程有关线程的所有管理工作都由在用户级实现的线程库来支持用户级线程特征用户级线程的创建和管理等操作无须内核参与,操作更快并行性不高,一个线程被系统阻塞后,整个进程被阻塞内核级线程内核级线程内核级线程的所有管理操作都是由操作系统内核完成的特点并行性高,多个线程可被同时调度充分利用多处理器创建和管理代价高线程计算模型用户级线程由可执行应用程序使用,同时由用户级操作系统管理内核级线程由操作系统内核使用,同时由内核操作系统处理硬件线程由每个处理器使用执行流程执行环境中的线程执行流程线程定义和准备线程运行线程执行由程序设计环境和编译器完成由操作系统采用进程完成由处理器完成用双向箭头表示线程在执行之后将结果返回到用户空间操作系统内部的线程操作系统被分为两个截然不同的层次:用户级(运行应用程序的层次)内核级(系统行为发生的层次)内核级是操作系统的核心,维护着大量用于追踪进程和线程的表格。内核级线程能够提供更高的性能。并且同一进程中的多个内核线程能够同时在不同的处理器或者执行核上执行。如OpenMP,PThread等线程库用内核级线程。硬件上的线程软件线程的指令都是由硬件来实际执行的。硬件上的多线程技术需要多个CPU来增加并行性。(每个线程都在独立的处理器上运行)多核CPU提供了两个或更多的执行核,能够支持真正的硬件多线程技术。线程的生命周期线程的标识通常用一个整数来标识一个线程线程的创建自动创建从main函数开始的主线程调用函数库接口创建一个新的线程(pthread_create)线程的终止执行完毕,或者调用了pthread_exit主线程退出导致整个进程会终止线程的状态线程的状态就绪(ready):线程等待可用的处理器。运行(running):线程正在被执行。阻塞(blocked):线程正在等待某个事件的发生(比如I/O的完成,试图加锁一个被上锁的互斥量)。终止(terminated):线程从起始函数中返回或者调用pthread_exit。线程状态的转换线程的同步由于线程共享同一进程的内存空间,多个线程可能需要同时访问同一个数据。如果没有正确的保护措施,对共享数据的访问会造成数据的不一致和错误。常用的同步机制:临界区(criticalsection)信号量(simphore)互斥量(mutex)管程(monitor)互斥量(mutex)在同一时刻只能有一个线程能够对互斥量加锁线程用互斥量对共享变量counter的互斥访问:pthread_mutex_tcount_mutex=PTHREAD_MUTEX_INITIALIZER;pthread_mutex_lock(&count_mutex); counter++;pthread_mutex_unlock(&count_mutex);信号量信号量被定义为一个整数变量,用两个原子的操作wait和signal来操作信号量wait:当执行wait时,如果信号量的值大于0,wait操作把信号量的值减1并返回;如果当前信号量的值为非正数则wait会等待。signalsignal操作对信号量的值加1,并唤醒哪些等待的进程条件变量如果要等待某个条件成立(比如x>y),当其他线程改变了共享变量的值时,线程应当重新测试该条件改变共享变量值的线程,给阻塞在条件变量上的线程发信号,唤醒该线程。典型的条件变量cond来测试x<=y的方法如下(mut为互斥量):1 pthread_mutex_lock(&mut);2 while(x<=y){3 pthread_cond_wait(&cond,&mut);4 }5 pthread_mutex_unlock(&mut);锁的粒度和死锁锁的粒度锁的粒度是上锁后保护的共享数据的多少减小锁的粒度可以提高对共享数据访问的并行性死锁两个线程分别拥有锁,并等待对方的锁死锁避免线程以相同的次序进行加锁非阻塞的加锁操作并行程序设计方法显式线程(Explicitthreading)微软Windows线程API,Pthreads,Java线程类等。利用编译器指导(Compiler-directed)自动并行,OpenMP,IntelThreadingBuildingBlocks等利用并行应用库(Parallellibraries)IntelIPP/MKL,ScaLAPACK,PARDISO,PLAPACK并行程序语言有150种以上消息传递(Messagepassing)MPI,OpenMP,PVM,等等。Windows环境下的多线程编程Windows线程库介绍Win32API是Windows操作系统为内核以及应用程序之间提供的接口,将内核提供的功能进行函数封装,应用程序通过调用相关的函数获得相应的系统功能。MFC是微软基础函数类库(MicrosoftFoundationClasses),由微软提供的,用类库的方式将Win32API进行封装,以类的方式提供给开发者。.NET

Framework

由两部分构成:公共语言运行库(Common

Language

Runtime

,CLR)和Framework类库(Framework

Class

Library

,FCL)。.NET基础类库的System.Threading命名空间提供了大量的类和接口来支持多线程。所有与多线程机制相关的类都存放在System.Threading命名空间中。创建线程管理线程使用Windows事件进行线程通信线程同步原子操作线程池线程优先级处理器亲和带有线程支持的用户级线程机制Windows多线程应用程序的编译和链接微软Win32/MFC线程API使用win32线程APIWin32函数库中提供了操作多线程的函数,包括创建线程、管理线程、终止线程、线程同步等接口。线程函数DWORDWINAPIThreadFunc(LPVOIDlpvThreadParm);线程创建HANDLECreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);也可以用_beginthread(多线程函数名,0,NULL)//须引入”process.h”使用win32线程API—HANDLE句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows中的句柄实际上是一个唯一的数字,它引用一个Windows对象,例如窗口或者图标等。。使用win32线程API—HANDLEWindows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象但是,必须注意的是程序每次重新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。使用WIN32线程API—

线程函数MyThreadStart(LPVOIDp)即为线程的执行函数线程函数—CreateThreadlpThreadAttribute Thisisoptionalsecurityforchildprocesses.ItcanbeNULL.这是子进程的可选安全性。它可以为NULL。dwStackSize Thisisstacksizeinbytes.Itcanbe0,whichmeansusedefault(usually1megabyte).这是堆栈大小(以字节为单位)。它可以是0,这意味着使用默认(通常是1兆字节)。lpStartAddress ThisisagloballyvisiblefunctiondeclaredDWORDWINAPI.Thisisthefunctionforthethreadtobeginexecution.这是一个全局可见的函数,声明为DWORDWINAPI。这是线程开始执行的函数。lpParameter Thisisapointertotheoneparameterfor"lpStartAddress"function.Useapointertoastructuretopassmultipleparameters.这是一个指向“lpStartAddress”函数的一个参数的指针。使用指向结构的指针传递多个参数。dwCreationFlags Thiscreatesathreadandstartsorsuspendsit.Use0tostart;otherwiseuseCREATE_SUSPENDED.这将创建一个线程并启动或暂停它。使用0开始;否则使用CREATE_SUSPENDED。lpThreadId Thisisanoutputparameterandreturnsaunique(acrossthesystem)integerforthethread.ItcanbeNULL.这是一个输出参数,并为线程返回一个唯一(跨系统)整数。它可以为NULL。线程管理设置线程的优先级线程优先级=进程优先级+线程相对优先级BoolSetThreadPriority(HANDLEhPriority,intnPriority)线程的挂起与恢复进程中的每个线程都有挂起计数器(suspendcount)。当挂起计数器值为0时,线程被执行;当挂起计数器值大于0时,调度器不去调度该线程。DWORDSuspendThread(HANDLEhThread);DWORDResumeThread(HANDLEhThread);线程等待一组能使线程阻塞其自身执行的等待函数WaitForSingleObject、WaitForMultipleObject。线程终结VOIDExitThread(DWORDdwExitCode);线程的退出释放操作系统资源在程序结束前要清除线程及其所占资源线程退出调用函数:

BOOLCloseHandle(HANDLEhObject);42Example:ThreadCreation#include<stdio.h>#include<windows.h>DWORDWINAPIhelloFunc(LPVOIDarg){printf(“HelloThread\n”);return0;}main(){ HANDLEhThread=CreateThread(NULL,0,helloFunc,NULL,0,NULL);}Whathappens?Whenprocessgoes,allthreadgo;43Example:ThreadCreation#include<stdio.h>#include<windows.h>BOOLthreadDone=FALSE;DWORDWINAPIhelloFunc(LPVOIDarg){printf(“HelloThread\n”);threadDone=TRUE;return0;}main(){ HANDLEhThread=CreateThread(NULL,0,helloFunc,NULL,0,NULL);while(!threadDone);}Agoodsolution?WaitingforaThreadWaitforoneobject(thread)Callingthreadwaits(blocks)until调用线程等待(块)直到•Timeexpires时间到期 •Returncodeusedtoindicatethis返回代码用于指示•Threadexits(handleissignaled)线程退出 •UseINFINITEtowaituntilthreadtermination使用INFINITE等待线程终止DoesnotuseCPUcycles不使用CPU周期45Example:ThreadCreation#include<stdio.h>#include<windows.h>DWORDWINAPIhelloFunc(LPVOIDarg){printf(“HelloThread\n”);return0;}main(){ HANDLEhThread=CreateThread(NULL,0,helloFunc, NULL,0,NULL);WaitForSingleObjects(hThread,INFINITE);}WaitingforManyThreadWaitforupto64objects(threads)Waitforall:fWaitAll==TRUEWaitforany:fWaitAll==FALSE•ReturnvalueisfirstarrayindexfoundNotesonWaitFor*FunctionsHandleasparameterUsedfordifferenttypesofobjects用于不同类型的对象Kernelobjectshavetwostates内核对象有两个状态 •Signaled信号 •Non-signaled无信号Behaviorisdefinedbyobjectreferredtobyhandle行为由句柄引用的对象定义 •Thread:signaledmeansterminated线程:用信号表示终止Example:MultipleThreadsModifythepreviousexamplecodetoprintout•Appropriate“HelloThread”message•Uniquethreadnumber•Usefor-loopvariableofCreateThreadloopSampleoutput:Example2:HelloThreadsExample2:HelloThreadsWhat’swrong?WhatisprintedformyNum?HelloThreadsTimeline数据竞争(RaceConditions)Concurrentaccessofsamevariablebymultiplethreads多个线程同时访问同一个变量•Read/Writeconflict读/写冲突•Write/Writeconflict写/写冲突Mostcommonerrorinconcurrentprograms并发程序中最常见的错误Maynotbeapparentatalltimes也许不是在任何时候都明显HowtoAvoidDataRacesScopevariablestobelocaltothreads范围变量为线程本地的•Variablesdeclaredwithinthreadedfunctions在线程函数中声明的变量•Allocateonthread’sstack在线程堆栈上分配•TLS(ThreadLocalStorage)线程本地存储Controlsharedaccesswithcriticalregions控制与关键区域的共享访问•Mutualexclusionandsynchronization互斥和同步•Lock,semaphore,event,criticalsection,mutex…锁定,信号量,事件,关键部分,互斥程序修改方案Solution–

“Local”StorageCanwork,butnotwiseidea!线程执行和资源存取线程之间通信的两个基本问题是互斥和同步线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应该等待,直到消息到达时才被唤醒。线程互斥是指对于共享资源,在各线程访问时的排它性。Win32线程同步的实现全局变量事件(Event)临界区(Criticalsection)互斥量(Mutex)信号量(Semaphore)Win32线程同步的实现(续)临界区一种防止多个线程同时执行一个特定代码段的机制适用于多个线程操作之间没有先后顺序但要求互斥的同步。多个线程访问同一个临界区的原则:一次最多只能一个线程停留在临界区内

不能让一个线程无限地停留在临界区内,否则其他线程将不能进入该临界区互斥量通常用于协调多个线程或进程的活动,通过“锁定”和“取消锁定”资源,控制对共享资源的访问。信号量信号量是一个核心对象,拥有一个计数器,可用来管理大量有限的系统资源。当计数值大于零时,信号量为有信号状态;当计数值为零时,信号量处于无信号状态。Win32线程同步的实现—全局变量使用全局变量保存线程中的关键数据或信息。Win32线程同步的实现—事件(Event)Usedtosignalotherthreadsthatsomeeventhasoccurred用于向其他线程发出一些事件发生的信号 •Dataisavailable,messageisready数据可用,消息就绪ThreadswaitforsignalwithWaitFor*function线程使用WaitFor*函数等待信号Twokindsofevents两种事件 •Auto-reset自动复位 •Manual-reset手动复位Caution:BecarefulwhenusingWaitForMultipleObjectstowaitforALLeventsWin32线程同步的实现—事件(Event)SetbManualResettoTRUEformanual-resetevent;FALSEforauto-resetevent手动复位为TRUE,自动复位为FALSESetbInitialStatetoTRUEforeventtobegininsignaledstate;FALSEtobeginunsignaledWin32线程同步的实现—事件(Event)Win32线程同步的实现—事件Win32线程同步的实现—CriticalSectionNewtype

•CRITICAL_SECTIONcs;Createanddestroyoperations

•InitializeCriticalSection(&cs)

•DeleteCriticalSection(&cs);Win32线程同步的实现—CriticalSectionWin32线程同步的实现—Mutexes Mutex对象的状态在它不被任何线程拥有时才有信号,而当它被拥有时则无信号。Mutex对象很适合用来协调多个线程对共享资源的互斥访问。 可按下列步骤使用该对象: 首先,建立互斥体对象,得到句柄:

HANDLECreateMutex(); 然后,在线程可能产生冲突的区域前(即访问共享资源之前)调用 WaitForSingleObject,将句柄传给函数,请求占用互斥对象:

dwWaitResult=WaitForSingleObject(hMutex,5000L); 共享资源访问结束,释放对互斥体对象的占用:

ReleaseMutex(hMutex); 互斥体对象在同一时刻只能被一个线程占用,当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才能成功。Win32线程同步的实现—MutexesWin32线程同步的实现—Mutexes(续)Win32线程同步的实现—Semaphore

信号对象允许同时对多个线程共享资源进行访问,在创建对象时指定最大可同时访问的线程数。当一个线程申请访问成功后,信号对象中的计数器减一,调用ReleaseSemaphore函数后,信号对象中的计数器加一。其中,计数器值大于或等于0,但小于或等于创建时指定的最大值。如果一个应用在创建一个信号对象时,将其计数器的初始值设为0,就阻塞了其他线程,保护了资源。等初始化完成后,调用ReleaseSemaphore函数将其计数器增加至最大值,则可进行正常的存取访问。可按下列步骤使用该对象:首先,创建信号对象:

HANDLECreateSemaphore();或者打开一个信号对象:HANDLEOpenSemaphore();然后,在线程访问共享资源之前调用:WaitForSingleObject;共享资源访问完成后,应释放对信号对象的占用: ReleaseSemaphore();Win32线程同步的实现—SemaphoreValueoflSemMaxmustbe1orgreaterValueoflSemInitialmustbe•greaterthanorequaltozero,•lessthanorequaltolSemMax,and•cannotgooutsideofrangeWin32线程同步的实现—Semaphore(续)UseWaitForSingleObjecttowaitonsemaphore•Ifcountis==0,threadwaits•Decrementcountby1whencount>0Incrementsemaphore(Postoperation)•IncreasesemaphorecountbycReleaseCount•ReturnsthepreviouscountthroughlpPreviousCountWin32线程同步的实现—Semaphore(举例)Mainthreadopensinputfile,waitsforthreadterminationThreadswillReadlinefrominputfileCountallfive-letterwordsinlineWin32线程同步的实现—Semaphore(举例续)Mainthreadopensinputfile,waitsforthreadterminationThreadswillReadlinefrominputfileCountallfive-letterwordsinlineMFC线程同步的实现AfxBeginThread()来创建一个CWinThread对象。CWinThread::CreateThread()函数用来启动新的线程MFC同步类CCriticalSection只允许当前进程中的一个线程访问某个对象的同步类CMutes只允许系统中一个进程内的一个线程访问某个对象的同步类CSymaphore只允许一到某个指定数目个线程同时访问某个对象的同步类CEvent当某个事件发生时通知一个应用程序的同步类微软.NET框架的线程API通用语言运行时(CommonLanguageRuntime:CLR)微软2002年引入的一种新的执行环境。C#.NET框架、CLR以及程序执行所需要的工具合起来,称为“.NET”。内容创建管理线程池同步①创建线程usingSystem;usingSystem.Threading;······Threadt=newThread(newThreadStart(ThreadProc));更为精练创建举例usingSystem;usingSystem.Threading;publicclassThreadExample{ publicstaticvoidThreadProc(){ for(inti=0;i<10;i++){ Console.WriteLine("ThreadProc:{0}",i); Thread.Sleep(0);}} publicstaticvoidMain(){ Console.WriteLine("Mainthread:Startasecondthread."); Threadt=newThread(newThreadStart(ThreadProc)); t.Start();

for(inti=0;i<4;i++){ Console.WriteLine("Mainthread:Dosomework."); Thread.Sleep(0);} Console.WriteLine("Mainthread:CallJoin(),towaituntilThreadProcends."); t.Join(); Console.WriteLine("Mainthread:ThreadProc.Joinhasreturned.PressEntertoendprogram."); Console.ReadLine();}}线程优先级优先级设置方法ThreadthreadOne=newThread(startDelegate);threadOne.Name="ThreadOne";ThreadthreadTwo=newThread(startDelegate);threadTwo.Name="ThreadTwo";threadTwo.Priority=ThreadPriority.BelowNormal;

threadOne.Start();threadTwo.Start();线程优先级优先级级别级别说明最高(Highest)可以将Thread安排在具有任何其他优先级的线程之前。

普通上(AboveNormal)可以将Thread安排在具有Highest优先级的线程之后,在具有Normal优先级的线程之前。

普通(Normal)可以将Thread安排在具有AboveNormal优先级的线程之后,在具有BelowNormal优先级的线程之前。默认情况下,线程具有Normal优先级。

普通下(BelowNormal)可以将Thread安排在具有Normal优先级的线程之后,在具有Lowest优先级的线程之前。

最低(Lowest)可以将Thread安排在具有任何其他优先级的线程之后。

②管理线程终止线程等待线程挂起合恢复线程Thre

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论