版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第二章Windows多線程編程1內(nèi)容Windows操作系統(tǒng)的一些基本知識Win32API線程庫線程間通信21、Windows操作系統(tǒng)的一些基本知識API內(nèi)核對象及句柄3API(ApplicationProgrammingInterface)API操作系統(tǒng)留給應(yīng)用程序的一個調(diào)用接口,應(yīng)用程序通過調(diào)用操作系統(tǒng)的API而使操作系統(tǒng)去執(zhí)行應(yīng)用程序的命令(動作)。WindowsAPI是一套用來控制Windows的各個部件的外觀和行為的預(yù)先定義的Windows函數(shù)。Win32API即為Microsoft32位平臺的應(yīng)用程序編程接口。Win32平臺上運行的應(yīng)用程序都可以調(diào)用這些函數(shù)。32與64位API函數(shù)聲明上沒有明顯區(qū)別,但64位編程是需要下載相應(yīng)的平臺SDK
4API(ApplicationProgrammingInterface)直接用win32API編寫的應(yīng)用程序,程序的執(zhí)行代碼小,運行效率高MFC用類庫的方式將win32API進行封裝,以類的方式提供給開發(fā)者Framework類庫提供了所有應(yīng)用程序模型都要使用的一個面向?qū)ο蟮腁PI集合5內(nèi)核對象及句柄當(dāng)應(yīng)用程序要與系統(tǒng)設(shè)備進行交互的時候,將使用到內(nèi)核對象。出于安全的考慮,進程是不能直接訪問內(nèi)核對象的,操作系統(tǒng)提供了對應(yīng)的函數(shù)來對它們進行訪問。內(nèi)核對象是由操作系統(tǒng)內(nèi)核分配,只能由內(nèi)核訪問的數(shù)據(jù)結(jié)構(gòu),用來管理各種系統(tǒng)資源。內(nèi)核對象包括:存取符號對象、事件對象、文件對象、作業(yè)對象、互斥對象、管道對象、等待計時器對象等都是內(nèi)核對象。編程時經(jīng)常要創(chuàng)建、打開和操作它們。6內(nèi)核對象及句柄內(nèi)核對象由內(nèi)核擁有,各個進程可以共享內(nèi)核對象。進程中止執(zhí)行,它使用的內(nèi)核對象并不一定會被撤銷。每個內(nèi)核對象都有一個計數(shù)器來存儲有多少個進程在使用它的信息。進程調(diào)用時,計數(shù)器增1,調(diào)用結(jié)束,計數(shù)器減1。內(nèi)核對象計數(shù)器為零時,銷毀此內(nèi)核對象。
7內(nèi)核對象及句柄內(nèi)核對象有安全描述符的保護,安全描述符描述了誰創(chuàng)建了該對象以及誰能夠使用該對象。用于創(chuàng)建內(nèi)核對象的函數(shù)幾乎都有一個指向SECURITY_ATTRIBUTES
結(jié)構(gòu)的指針作為其參數(shù)。
大多數(shù)應(yīng)用程序通過傳NULL值,創(chuàng)建具有默認安全性的對象。如果想限制別人對對象的訪問,就需要單獨創(chuàng)建一個SECURITY_ATTRIBUTES對象并對其初始化。8內(nèi)核對象及句柄句柄:創(chuàng)建內(nèi)核對象時,函數(shù)的返回值,標記該內(nèi)核對象。句柄表:進程被初始化時,系統(tǒng)給進程分配一個句柄表,用于保存該進程使用的內(nèi)核對象的信息,而句柄值則是相應(yīng)內(nèi)核對象在句柄表中的索引值,因此句柄值是進程相關(guān)的。9內(nèi)核對象及句柄內(nèi)核對象創(chuàng)建當(dāng)利用creat*函數(shù)來創(chuàng)建內(nèi)核對象時,調(diào)用該函數(shù)的時候內(nèi)核就為該對象分配一個內(nèi)存塊,并進行初始化,然后內(nèi)核再掃描該進程的句柄表,初始化一條記錄并放在句柄表中。關(guān)閉內(nèi)核對象無論進程怎樣創(chuàng)建內(nèi)核對象,在不使用該對象的時候都應(yīng)當(dāng)通過Bool
CloseHandle(HANDLE
hobj)來向操作統(tǒng)聲明結(jié)束對該對象的訪問。10Win32API線程庫創(chuàng)建線程的基本問題創(chuàng)建線程的API函數(shù)操作線程的API一個簡單的Windows多線程程序111創(chuàng)建線程的基本問題線程可以由進程中的任意線程創(chuàng)建,而進程的主線程在進程加載時自動創(chuàng)建。每個線程都有自己的進入點函數(shù)。主線程的進入點函數(shù)進入點應(yīng)用程序類型WinMain需要ANSI字符和字符串的GUI應(yīng)用程序wWinMain需要Unicode字符和字符串的GUI應(yīng)用程序Main需要ANSI字符和字符串的CUI應(yīng)用程序Wmain需要Unicode字符和字符串的CUI應(yīng)用程序12線程函數(shù)的返回值是該線程的退出代碼線程函數(shù)應(yīng)盡可能使用函數(shù)參數(shù)和局部變量線程函數(shù)----線程的入口點DWORDWINAPIThreadFunc(PVOIDpvParam){ DWORDdwResult=0; … … return(dwResult);}132創(chuàng)建線程的API函數(shù)創(chuàng)建線程:系統(tǒng)創(chuàng)建一個線程內(nèi)核對象。線程內(nèi)核對象不是線程本身,而是操作系統(tǒng)用來管理線程的較小的數(shù)據(jù)結(jié)構(gòu)在進程的地址空間分配內(nèi)存,供線程的堆棧使用14HANDLECreateThread(PSECURITY_ATTRIBUTESpsa,DWORDcbStack,PTHREAD_START_ROUTINEpStartAddr,PVOIDpvParam,DWORDfdwCreate,PDWORDpdwThreadId);2創(chuàng)建線程的API函數(shù)NULL0函數(shù)地址函數(shù)參數(shù)NULL控制創(chuàng)建線程標志CREATE_SUSPENDED;0線程ID15暫停線程DWORDSuspendThread(HANDLEhThread)返回值是線程的前一個暫停計數(shù)暫停計數(shù):是線程內(nèi)核對象的一個內(nèi)部值。使用要小心,因為不知道暫停線程運行時它在進行什么操作。可能造成死鎖3操作線程的API163操作線程的API恢復(fù)線程DWORDResumeThread(HANDLEhThread);返回值是線程的前一個暫停計數(shù)該函數(shù)用于將處于暫停狀態(tài)的線程置于就緒狀態(tài),使其參加線程調(diào)度。173操作線程的API使線程睡眠VOIDSleep(DWORDdwMilliseconds);該函數(shù)是線程暫停自己的運行,直到睡眠時間過去為止當(dāng)線程調(diào)用這個函數(shù)時,它自動放棄剩余的時間片,迫使系統(tǒng)進行線程調(diào)度。Windows不是實時的操作系統(tǒng)。183操作線程的API終止線程線程函數(shù)返回(最好)通過調(diào)用ExitThread函數(shù),線程將自行撤銷同一個進程或另一個進程中的線程調(diào)用TerminateThread函數(shù)包含線程的進程終止19線程返回函數(shù)線程中創(chuàng)建的C++類對象能夠正常撤銷;操作系統(tǒng)將正確地釋放線程堆棧使用的內(nèi)存;系統(tǒng)將線程的退出代碼設(shè)置為線程函數(shù)的返回值;系統(tǒng)將遞減線程內(nèi)核對象的使用計數(shù)。20線程調(diào)用這個函數(shù),強制線程終止運行;操作系統(tǒng)清除該線程使用的所有系統(tǒng)資源。C++類對象將不被撤銷。VOIDExitThread(DWORDdwExitCode);ExitThread函數(shù)21能夠撤銷任何線程;線程的內(nèi)核對象的使用計數(shù)也被遞減;異步運行的函數(shù);不撤銷線程的堆棧,直到進程終止。BOOLTerminateThread(HANDLEhThread,DWORDdwExitCode);TerminateThread函數(shù)22在進程終止運行時撤銷線程ExitProcess和TerminateProcess函數(shù)可以終止線程,將會終止進程中的所有線程;ExitProcess只能強制執(zhí)行本進程的退出;TerminateProcess在一個進程中強制結(jié)束其他的進程;進程所使用的資源被清除;C++對象撤銷函數(shù)沒有被調(diào)用。VOIDExitProcess(UINTuExitCode);BOOLTerminateProcess(HANDLEhProcess,UINTuExitCode);2324在進程終止運行時撤銷線程254一個簡單的Windows多線程程序(例1)include"windows.h"#include<iostream>usingnamespacestd;DWORDWINAPIThreadFunc(PVOIDpvParam){ cout<<"Createdthreadsays'helloWorld!'"<<endl; return0;}intmain(){ HANDLEThreadHandle=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL); Sleep(100); cout<<"Mainthreadsays'HelloWorld!"<<endl; getchar(); return0;}26線程間通信操作系統(tǒng)隨機調(diào)度線程,程序員不能預(yù)知線程的執(zhí)行順序下面兩種情況下,線程間需要通信當(dāng)有多個線程訪問共享資源而不希望共享資源遭到破壞;(互斥)當(dāng)一個線程需要將某個任務(wù)已經(jīng)完成的情況通知另外一個或多個線程時。(同步)Windows線程通信方法主要有互鎖函數(shù)、臨界段、事件、互斥量、信號量27線程間通信互鎖函數(shù)臨界段事件互斥量信號量281、互鎖函數(shù)互鎖函數(shù)是用來解決原子訪問的,主要針對變量的原子訪問;原子訪問:當(dāng)線程訪問資源時,能夠確保沒有其它線程同時訪問相同的資源。29Longg_x=0;//全局變量DWORDWINAPIThreadFunc1(PVOIDpvParam){ g_x++;return0;}DWORDWINAPIThreadFunc2(PVOIDpvParam){ g_x++;return0;}MOVEAX,[g_x]INCEAXMOV[g_x],EAX遞增以原子方式運行1、互鎖函數(shù)(例)301、互鎖函數(shù)LONGInterlockedExchangeAdd()(PLONGplAddend,LONGlIncrement);Longg_x=0;//全局變量DWORDWINAPIThreadFunc1(PVOIDpvParam){ InterlockedExchangeAdd(&g_x,1);return0;}DWORDWINAPIThreadFunc2(PVOIDpvParam){ InterlockedExchangeAdd(&g_x,1);return0;}311、互鎖函數(shù)以原子操作方式用第二個參數(shù)的值取代第一個參數(shù)的當(dāng)前值。LONGInterlockedExchange()(PLONGplTarget,LONGlValue);LONGInterlockedExchangePointer()(PVOID*ppvTarget,PVOIDpvValue);321、互鎖函數(shù)比較第一個參數(shù)所指的值和第三個參數(shù)的值,如果相等,則將第一個參數(shù)所指的值置為第二個參數(shù),如果不相等則不進行任何操作。LONGInterlockedCompareExchange()(PLONGplDestination,LONGlExchange,LONGlComparand);LONGInterlockedCompareExchangePointer()(PVOID*ppvDestination,PVOIDpvExchange,PVOIDpvComparand);332、臨界段互鎖函數(shù):以原子操作方式修改單個值臨界段:以原子方式修改復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。臨界段:關(guān)鍵代碼段,是指一小段代碼,同一個時刻,只能有一個線程具有訪問權(quán)。多個線程訪問同一個臨界區(qū)的原則:一次最多只能一個線程停留在臨界區(qū)內(nèi);不能讓一個線程無限地停留在臨界區(qū)內(nèi),否則其它線程將不能進入該臨界區(qū)342、臨界段相關(guān)API函數(shù)首先定義一個臨界段對象(通常全局變量)CRITICAL_SECTIONcs臨界段對象初始化InitializeCriticalSection(&cs)
進入臨界段EnterCriticalSection(&cs)離開臨界段LeaveCriticalSection(&cs)釋放臨界段對象DeleteCriticalSection(&cs)35臨界段例#include<windows.h>#include<fstream>fstreamfile;DWORDWINAPIThreadFunc1(PVOIDparam){ for(inti=1;i<=1000;i++) { file<<"ThreadFunc1Output"<<i<<endl; } return0;}DWORDWINAPIThreadFunc2(PVOIDparam){ for(inti=1;i<=1000;i++) { file<<"ThreadFunc2Output"<<i<<endl; } return0;}36intmain(){("data.txt",ios::out); HANDLEThreadHandle1=CreateThread(NULL,0,ThreadFunc1,NULL,0,NULL); HANDLEThreadHandle2=CreateThread(NULL,0,ThreadFunc2,NULL,0,NULL); HANDLEhThread[2]={ThreadHandle1,ThreadHandle2}; WaitForMultipleObjects(2,hThread,TRUE,INFINITE);
(); return0;}37加上臨界段#include<windows.h>#include<fstream>fstreamfile;CRITICAL_SECTIONcs;DWORDWINAPIThreadFunc1(PVOIDparam){ for(inti=1;i<=1000;i++) { EnterCriticalSection(&cs); file<<"ThreadFunc1Output"<<i<<endl; LeaveCriticalSection(&cs); } return0;}38DWORDWINAPIThreadFunc2(PVOIDparam){ for(inti=1;i<=1000;i++) { EnterCriticalSection(&cs); file<<"ThreadFunc2Output"<<i<<endl; LeaveCriticalSection(&cs); } return0;}39使用內(nèi)核對象的線程間通信互鎖函數(shù)和臨界段都是在用戶態(tài)實現(xiàn)線程通信的,優(yōu)點速度快用戶態(tài)機制只能實現(xiàn)同一進程內(nèi)線程通信。內(nèi)核對象機制可以實現(xiàn)不同進程內(nèi)線程的通信,缺點速度慢。包含通知狀態(tài)和未通知狀態(tài)內(nèi)核屬性的內(nèi)核對象有:進程,線程,作業(yè),文件,控制臺輸入文件修改通知,事件,可等待定時器信號量,互斥量40等待函數(shù):使線程進入等待狀態(tài),直到一個對象變?yōu)橐淹ㄖ獱顟B(tài)。DWORDWaitForSingleObject(
HANDLEhHandle,
DWORDdwMilliseconds
);參數(shù)dwMilliseconds有兩個特殊值:0,則該函數(shù)立即返回;INFINITE,則線程被掛起,直到hHandle所指向的對象變?yōu)橐淹ㄖ獱顟B(tài)。使用內(nèi)核對象的線程間通信41等待函數(shù):可以保證線程的同步。DWORDWaitForMultipleObject(DWORDdwCount,
CONSTHANDLE*phHandle,BOOLfWaitAll,
DWORDdwMilliseconds
);使用內(nèi)核對象的線程間通信423、事件事件內(nèi)核對象是最簡單的對象。一個使用計數(shù)一個布爾值,指明該事件是自動重置事件(false),還是人工重置事件(true);一個布爾值,指明該事件是已通知狀態(tài),還是未通知狀態(tài)。當(dāng)人工重置事件得到通知時,等待該事件的所有線程均變?yōu)榭烧{(diào)度事件;當(dāng)自動重置事件得到通知時,等待該事件的線程中只有一個線程變?yōu)榭烧{(diào)度線程。43創(chuàng)建事件內(nèi)核對象,返回句柄。HANDLECreateEvent(
PSECURITY_ATTRIBUTESpsa,//安全屬性
BOOLfManualReset,//重置方式
BOOLfInitialState,//初始狀態(tài)
PCTSTRpszName//對象名稱
);3、事件44其它進程中的線程可以獲得事件對象的訪問權(quán)HANDLEOpenEvent(
DWORDfdwAccess,
BOOLfInherit,
PCTSTRpszName
);EVENT_ALL_ACCESS3、事件45一旦事件已經(jīng)創(chuàng)建,就可以直接控制它的狀態(tài)將事件設(shè)置為已通知狀態(tài)BOOLSetEvent(HANDLEhEvent);將事件設(shè)置為未通知狀態(tài)BOOLResetEvent(HANDLEhEvent);3、事件463、事件事件的主要用途是標志事件的發(fā)生,并以此協(xié)調(diào)線程的執(zhí)行順序。例子:用戶在主線程輸入命令,控制新建線程的運行。47#include<windows.h>#include<iostream>#include<string>usingnamespacestd;CRITICAL_SECTIONcs;DWORDWINAPIThreadFunc(PVOIDparam){EnterCriticalSection(&cs);cout<<"CreateThread:Createthreadisstarted"<<endl;cout<<"CreateThread:Createthreadiswaitingcontinuecommand.."<<endl;LeaveCriticalSection(&cs);HANDLEphEvent=OpenEvent(EVENT_ALL_ACCESS,TRUE,"ContinueCommand");WaitForSingleObject(phEvent,INFINITE);cout<<"CreateThread:Recievedcontinuecommand."<<endl;cout<<"CreateThread:Threadrunsagain."<<endl;Sleep(2000);cout<<"CreateThread:Threadfinished."<<endl;return0;}48intmain(){ InitializeCriticalSection(&cs); HANDLEhEvent=CreateEvent(NULL,FALSE,FALSE,"ContinueCommand"); cout<<"MainThread:Creatingnewthread."<<endl; HANDLEThreadHandle=CreateThread(NULL,0,ThreadFunc,NULL,CREATE_SUSPENDED,NULL); cout<<"MainThread:Newthreadcreated."<<endl; ResumeThread(ThreadHandle); stringinput; while(TRUE) { EnterCriticalSection(&cs); cout<<"MainThread:inputcommand,please"<<endl; LeaveCriticalSection(&cs); cout<<">";
49 cin>>input; if(input=="continue") { cout<<"MainThread:Letthreadcontinuerun"<<endl; SetEvent(hEvent); break; } }
WaitForSingleObject(ThreadHandle,INFINITE); cout<<"MainThread:Createthreadfinished"<<endl; DeleteCriticalSection(&cs); CloseHandle(hEvent); return0;}504、互斥量互斥量是一個種內(nèi)核對象,確保線程擁有對單個資源的互斥訪問權(quán)。一個使用數(shù)量一個線程ID一個遞歸計數(shù)器互斥量的行為特征與臨界段相同,互斥量屬于內(nèi)核對象,而臨界段屬于用戶方式對象?;コ饬康木€程ID標識系統(tǒng)中哪個線程擁有互斥量,為0,沒有線程擁有遞歸計數(shù)器指明線程擁有互斥量的次數(shù)514、互斥量經(jīng)常用于保護多個線程訪問的內(nèi)存塊;控制對共享資源的訪問保證每次只能有一個線程獲得互斥量524、互斥量互斥量的創(chuàng)建,返回句柄HANDLECreateMutex(PSECURITY_ATTRIBUTESpsa,//安全屬性的指針
BOOLbInitialOwner,//初始化互斥對象的所有者
PCTSTRpszName
//指向互斥對象名的指針
);534、互斥量另一個進程可獲得本進程相關(guān)的互斥量的句柄HANDLEOpenMutex(
DWORDfdwAccess,//access
BOOLbInheritHandle,//inheritanceoption
PCTSTRpszName//objectname
);54釋放互斥量HANDLEReleaseMutex(
HANDLEhMutex
);等待互斥量DWORDWaitForSingleObject(
HANDLEhHandle,
DWORDdwMilliseconds
);互斥量不同于其它內(nèi)核對象,互斥對象有一個“線程所有權(quán)”的概念。4、互斥量55#include<windows.h>#include<fstream>usingnamespacestd;fstreamfile;DWORDWINAPIThreadFunc1(PVOIDparam){ HANDLE*phMutex=(HANDLE*)param; for(inti=1;i<=100;i++) { WaitForSingleObject(*phMutex,INFINITE); file<<"ThreadFunc1Output"<<i<<endl; ReleaseMutex(*phMutex); } return0;}56DWORDWINAPIThreadFunc2(PVOIDparam){ HANDLE*phMutex=(HANDLE*)param; for(inti=1;i<=100;i++) { WaitForSingleObject(*phMutex,INFINITE); file<<"ThreadFunc2Output"<<i<<endl; ReleaseMutex(*phMutex); } return0;}57intmain(){ ("data.txt",ios::out); HANDLEhMutex=CreateMutex(NULL,FALSE,"DisplayMutex"); HANDLEThreadHandle1=CreateThread(NULL,0,ThreadFunc1,&hMutex,0,NULL); HANDLEThreadHandle2=CreateThread(NULL,0,ThreadFunc2,&hMutex,0,NULL); HANDLEhThread[2]={ThreadHandle1,ThreadHandle2}; WaitForMultipleObjects(2,hThread,TRUE,INFINITE); CloseHandle(hMutex); (); return0;}585、信號量信號量是一個內(nèi)核對象,可用來管理大量有限的系統(tǒng)資源一個使用計數(shù)32位整數(shù),最大資源數(shù)量32位整數(shù),當(dāng)前資源數(shù)量信號量使用規(guī)則:當(dāng)前資源數(shù)量大于0,則等待信號量的線程獲得資源繼續(xù)運行,當(dāng)前資源數(shù)量減1當(dāng)前資源數(shù)量等于0,則等待信號量的線程繼續(xù)等待,直到有線程釋放信號量,使當(dāng)前資源數(shù)量大于059創(chuàng)建信號量5、信號量HANDLECreateSemaphore(
PSECURITY_ATTRIBUTESpsa,
LONGlInitialCount,//initialcount
LONGlMaximumCount,//maximumcount
PCTSTRpszName//objectname
);60另一進程可獲得與本進程相關(guān)的信號量的句柄5、信號量HANDLEOpenSemaphore(
DWORDfdwAccess,
BOOLbInheritHandle,//inheritanceoption
PCTSTRpszName//objectname
);61釋放信號量例,兩個線程分別有一個初值為0的Int型局部變量,兩個線程的行為是在一個循環(huán)中,使整型變量遞增,一個約束條件,在遞增過程中,這兩個值的差不超過5ReleaseSemaphore(
HANDLEhSem,
LONGlReleaseCount,
PLONGplPreviousCount
);5、信號量62HANDLEhsem1=CreateSemaphore(NULL,5,10,"sem1");HANDLEhsem2=CreateSemaphore(NULL,5,10,"sem2");inti1=0;inti2=0;DWORDWINAPIThreadFunc1(PVOIDparam){ for(inti=1;i<=100;i++) { WaitForSingleObject(hsem1,INFINITE); ReleaseSemaphore(hsem2,1,NULL); i1++; file<<"i1="<<i1<<"i2="<<i2<<endl; } return0;}63DWORDWINAPIThreadFunc2(PVOIDparam){ for(inti=1;i<=100;i++) { WaitForSingleObject(hsem2,INFINITE); ReleaseSemaphore(hsem1,1,NULL); i2++; file<<"i1="<<i1<<"i2="<<i2<<endl; } return0;}64線程的優(yōu)先級決定它何時運行和接收多少CPU時間。優(yōu)先級共32級,是從0到31的數(shù)值,稱為基本優(yōu)先級別。0-15級是普通優(yōu)先級線程的優(yōu)先級可以動態(tài)變化高
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 修理工崗位培訓(xùn)管理制度
- 藝術(shù)培訓(xùn)教職工管理制度
- 職業(yè)病防治培訓(xùn)制度
- 書法培訓(xùn)班老師規(guī)章制度
- 培訓(xùn)復(fù)訓(xùn)規(guī)章制度
- 職場人員自費培訓(xùn)制度
- 血透??婆嘤?xùn)與考核制度
- 員工封閉培訓(xùn)管理制度
- 團干部培訓(xùn)班制度
- 培訓(xùn)機構(gòu)學(xué)生到校制度
- 2023年版測量結(jié)果的計量溯源性要求
- 建筑能耗與碳排放研究報告
- GB 29415-2013耐火電纜槽盒
- 中國古代經(jīng)濟試題
- 真空采血管的分類及應(yīng)用及采血順序課件
- 軟件定義汽車:產(chǎn)業(yè)生態(tài)創(chuàng)新白皮書
- 安裝工程實體質(zhì)量情況評價表
- 動力觸探試驗課件
- 城市軌道交通安全管理課件(完整版)
- 八大浪費培訓(xùn)(整理)
- 幼兒園機器人課件.ppt
評論
0/150
提交評論