版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
基于OpenHarmony的嵌入式開發(fā)
第三章OpenHarmony內(nèi)核進階分析安全邊距3.1進程間通信[3.1.0]進程間通信簡介
LiteOS-M調(diào)度對象是任務(wù)Task,LiteOS-A是進程Process和任務(wù)進程間通信(Inter-ProcessCommunication,IPC)指操作系統(tǒng)提供的,供進程(任務(wù))之間共享數(shù)據(jù)的機制和方法,應(yīng)用程序可以通過IPC實現(xiàn)相互之間的通信,IPC關(guān)系著操作系統(tǒng)內(nèi)核的效率問題。
LiteOS-M所支持的IPC類型包括:事件(Event)、互斥鎖(Mutex)、隊列(Queue)和信號量(Semaphore)。
LiteOS-A除了支持上述類型之外,還支持信號(Signal)和用戶態(tài)快速互斥鎖(Futex)等。
IPC具有很強的通用性,本小節(jié)不區(qū)分LiteOS-M和LiteOS-A?;贠penHarmony的嵌入式開發(fā)2安全邊距3.1進程間通信[3.1.1]事件Event事件:用于任務(wù)間的同步操作接口:事件初始化、事件讀寫、事件清零、事件銷毀等表示:用32位無符號整型變量來表示的,其中每一位表示一種事件類型,LiteOS共表達了31種可用的事件類型(第25位不可用)?;贠penHarmony的嵌入式開發(fā)3/***@ingrouplos_event*Eventcontrolstructure*/typedefstructtagEvent{UINT32uwEventID;
/**<Eventmaskintheeventcontrolblock,
indicatingtheeventthathasbeenlogicallyprocessed.*/LOS_DL_LISTstEventList;
/**<Eventcontrolblocklinkedlist*/}EVENT_CB_S,*PEVENT_CB_S;事件控制塊安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的特點:(1)任務(wù)間的事件同步,可以是一對多,也可以多對多的。一對多表示一個任務(wù)可以等待多個事件,多對多則表示多個任務(wù)可以等待多個事件。但是一次寫事件最多觸發(fā)一個任務(wù)從阻塞中醒來。(2)事件具有讀超時機制。(3)事件只做任務(wù)間同步,不傳輸具體數(shù)據(jù)。(4)多次向事件控制塊寫入同一事件類型,在被清零前等效于只寫入一次。(5)多個任務(wù)可以對同一事件進行讀寫操作。(6)支持事件讀寫超時機制。基于OpenHarmony的嵌入式開發(fā)4安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例基于OpenHarmony的嵌入式開發(fā)5創(chuàng)建一個事件控制塊,通過該控制塊維護一個已處理的事件集合,以及等待特定事件的任務(wù)鏈表。向事件控制塊中寫入指定的事件。事件控制塊更新事件集合,并遍歷任務(wù)鏈表,根據(jù)任務(wù)等待具體條件滿足情況決定是否喚醒相關(guān)任務(wù)。如果讀取的事件已存在則會直接同步返回。其他情況會根據(jù)超時時間或事件觸發(fā)情況來決定返回時機。如果等待的事件條件在超時時間耗盡之前到達,則阻塞任務(wù)會被直接喚醒,否則只能在超時時間耗盡時,該任務(wù)才會被喚醒。讀事件條件滿足與否取決于參數(shù)eventMask(掩碼)和mode(模式)。LOS_EventInit
LOS_EventWrite
LOS_EventRead
LOS_EventPool
安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例基于OpenHarmony的嵌入式開發(fā)6完成程序既定的功能后,還需要根據(jù)指定掩碼,對事件控制塊的事件集合進行清零操作。當(dāng)掩碼為0時,表示將事件集合全部清零。當(dāng)掩碼為0xffff時,表示不清除任何事件,保持事件集合原狀。向事件控制塊中寫入指定的事件。事件控制塊更新事件集合,并遍歷任務(wù)鏈表,根據(jù)任務(wù)等待具體條件滿足情況決定是否喚醒相關(guān)任務(wù)。銷毀指定的事件控制塊LOS_EventClear
LOS_EventDestroy
LOS_EventInit
LOS_EventWrite
LOS_EventRead
LOS_EventPool
安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:一種開發(fā)流程參考(1)初始化事件控制塊;(2)阻塞讀事件控制塊;(3)寫入相關(guān)事件;(4)阻塞任務(wù)被喚醒,讀取事件并檢查是否滿足要求;(5)處理事件控制塊;(6)事件控制塊銷毀。基于OpenHarmony的嵌入式開發(fā)7初始化后的任意時間、任意程序完成STATICINLINEVOIDOsWatchCmdUsage(VOID)
{PRINTK("\nUsage:watch\n");PRINTK("watch[options]command\n");}watch命令:周期性監(jiān)測某個命令的運行狀態(tài)安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:watch命令執(zhí)行機制課堂思考問題:watch命令是如何執(zhí)行的基于OpenHarmony的嵌入式開發(fā)8/kernel/liteos_a/shell/full/src/cmds/watch_sehllcmd.cSHELLCMD_ENTRY()OsShellCmdWatch()
OsWatchCmdUsage()OsWatchOverFunc()OsWatchTaskCreate()if((argc==1)&&(strcmp(argv[0],"--over")==0)){ret=OsWatchOverFunc();
returnret;}if(argc==0){OsWatchCmdUsage();returnOS_ERROR;}if(argv==NULL){OsWatchCmdUsage();returnOS_ERROR;}argc:argumentcount,傳入的參數(shù)個數(shù)argc==0:傳入?yún)?shù)數(shù)量為0(調(diào)用命令不合法)argv:argumentvector,傳入的參數(shù)列表argv==NULL:沒有傳入?yún)?shù)(調(diào)用命令不合法)STATICINLINEVOIDOsWatchCmdUsage(VOID)
{PRINTK("\nUsage:watch\n");PRINTK("watch[options]command\n");}watchItem=(WatchCB*)malloc(sizeof(WatchCB));(VOID)memset_s(watchItem,sizeof(WatchCB),0,sizeof(WatchCB));……;err=OsWatchOptionParsed(argc,&argoff,argv,watchItem);……;err=OsWatchCmdSplice(argc,argoff,argv,watchItem);……;ret=OsWatchTaskCreate(watchItem);LOS_EventWrite(&g_watchCmd->watchEvent,0x01);安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:watch命令執(zhí)行機制課堂思考問題:watch命令是如何執(zhí)行的基于OpenHarmony的嵌入式開發(fā)9SHELLCMD_ENTRY()OsShellCmdWatch()
OsWatchCmdUsage()OsWatchOverFunc()OsWatchTaskCreate()ret=OsWatchTaskCreate(watchItem);UINT32OsWatchTaskCreate(WatchCB*watchItem){
UINT32watchTaskId=0;
……;
ret=LOS_EventInit(&watchItem->watchEvent);
if(ret!=0){
……
}
initParam.pfnTaskEntry=(TSK_ENTRY_FUNC)OsShellCmdDoWatch;initParam.usTaskPrio=10;
/*10:shellcmd_watchtaskpriority*/initParam.auwArgs[0]=(UINTPTR)watchItem;initParam.uwStackSize=0x3000;
/*0x3000:stacksizeofshellcmd_watchtask*/initParam.pcName="shellcmd_watch";initParam.uwResved=LOS_TASK_STATUS_DETACHED;
ret=LOS_TaskCreate(&watchTaskId,&initParam);if(ret!=0){
……
}returnret;}核心功能安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:watch命令執(zhí)行機制-核心功能基于OpenHarmony的嵌入式開發(fā)10STATICVOIDOsShellCmdDoWatch(UINTPTRarg1)
{
WatchCB*watchItem=(WatchCB*)arg1;
……while(watchItem->count--){printf("\033[2J\n");if(watchItem->title){
PrintTime();}(VOID)ShellMsgParse(watchItem->cmdbuf);ret=LOS_EventRead(&watchItem->watchEvent,0x01,LOS_WAITMODE_OR|LOS_WAITMODE_CLR,
watchItem->interval);if(ret==0x01){break;}}(VOID)LOS_EventDestroy(&watchItem->watchEvent);
……}STATICVOIDPrintTime(VOID)
{structtimeval64stNowTime={0};if(gettimeofday64(&stNowTime,NULL)==0){PRINTK("%s",ctime64(&(stNowTime.tv_sec)));}}typedefstruct{BOOLtitle;/*whethertohidethetimestamps*/UINT32count;/*thetotalnumberofcommandexecutions*/UINT32interval;/*runningcycleofthecommand*/
EVENT_CB_SwatchEvent;/*eventhandleofthewatchstructure*/
CHARcmdbuf[CMD_MAX_LEN];/*thecommandtowatch*/}WatchCB;安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:watch命令執(zhí)行機制-核心功能基于OpenHarmony的嵌入式開發(fā)11STATICVOIDOsShellCmdDoWatch(UINTPTRarg1)
{WatchCB*watchItem=(WatchCB*)arg1;
……while(watchItem->count--){printf("\033[2J\n");if(watchItem->title){PrintTime();}
(VOID)ShellMsgParse(watchItem->cmdbuf);ret=LOS_EventRead(&watchItem->watchEvent,0x01,LOS_WAITMODE_OR|LOS_WAITMODE_CLR,
watchItem->interval);if(ret==0x01){break;}}(VOID)LOS_EventDestroy(&watchItem->watchEvent);
……}externUINT32LOS_EventRead(PEVENT_CB_SeventCB,UINT32eventMask,UINT32mode,UINT32timeOut);eventCB:PointertotheeventcontrolblocktobecheckedeventMask:Maskoftheeventexpectedtooccurbytheuser,indicatingtheeventobtainedaftermode
:Eventreadingmode.timeOut:Timeoutintervalofeventreading(unit:Tick).retval0:Theeventexpectedbytheuserdoesnotoccur.retval#UINT32:Theeventexpectedbytheuseroccurs.返回值為0時,表示設(shè)定的事件并未發(fā)生,返回其他32位數(shù)值時表示發(fā)生了該事件。LOS_EventWrite(&g_watchCmd->watchEvent,0x01);列印出命令的執(zhí)行信息循環(huán)檢測事件安全邊距3.1進程間通信[3.1.1]事件(Event)LitsOS事件的運作流程示例:watch
task基于OpenHarmony的嵌入式開發(fā)12PrintTime();ShellMsgParse(watchItem->cmdbuf);1事件有沒有傳遞信息?有2事件傳遞了什么信息?狀態(tài)(單一數(shù)值信息,例如0x01)安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖(互斥量):一種特殊的二值性信號量,使用或未被使用狀態(tài)
實現(xiàn)獨占式訪問:實現(xiàn)對共享資源的獨占式處理,在有多個線程執(zhí)行的環(huán)境中強制限制對資源的訪問,實現(xiàn)對共享資源的保護基于OpenHarmony的嵌入式開發(fā)13/***@ingrouplos_mux*Mutexobject.*/typedefstruct{UINT8muxStat;/**<StateOS_MUX_UNUSED,OS_MUX_USED*/UINT16muxCount;/**<Timesoflockingamutex*/UINT32muxID;/**<HandleID*/LOS_DL_LISTmuxList;/**<Mutexlinkedlist*/LosTaskCB*owner;/**<Thecurrentthreadthatislockingamutex*/UINT16priority;/**<Priorityofthethreadthatislockingamutex*/}LosMuxCB;LiteOS-M互斥鎖控制塊安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:使用時上鎖(申請)、未被使用狀態(tài)時釋放基于OpenHarmony的嵌入式開發(fā)14線程1訪問某個公共資源,互斥鎖上鎖,線程2不能訪問被掛起。線程1釋放該公共資源,互斥鎖釋放,線程2才能夠訪問該公共資源。安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:LiteOS-M和LiteOS-A的互斥鎖接口基于OpenHarmony的嵌入式開發(fā)15LiteOS-M接口接口功能說明LOS_MuxCreate創(chuàng)建互斥鎖LOS_MuxDelete刪除指定的互斥鎖LOS_MuxPend申請指定的互斥鎖LOS_MuxPost釋放指定的互斥鎖LiteOS-A接口名稱接口功能說明LOS_MuxInit互斥鎖初始化LOS_MuxDestroy銷毀指定的互斥鎖LOS_MuxLock申請指定的互斥鎖LOS_MuxTrylock嘗試申請指定的互斥鎖,不阻塞LOS_MuxUnlock釋放指定的互斥鎖LOS_MuxIsValid判斷互斥鎖釋放有效LOS_MuxAttrInit互斥鎖屬性初始化LOS_MuxAttrDestroy銷毀指定的互斥鎖屬性…………LiteOS-A的互斥鎖更加復(fù)雜復(fù)雜在屬性上typedefstruct{UINT8protocol;UINT8prioceiling;UINT8type;UINT8reserved;}LosMuxAttr;安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:LiteOS-A的復(fù)雜屬性基于OpenHarmony的嵌入式開發(fā)16typedefstruct{UINT8protocol;UINT8prioceiling;UINT8type;UINT8reserved;}LosMuxAttr;協(xié)議屬性:處理不同優(yōu)先級的任務(wù)申請互斥鎖(1)LOS_MUX_PRIO_NONE,該屬性不對申請互斥鎖的任務(wù)的優(yōu)先級進行繼承或保護操作。(2)LOS_MUX_PRIO_INHERIT,該屬性為優(yōu)先級的繼承屬性,是互斥鎖的默認屬性,對申請互斥鎖的任務(wù)的優(yōu)先級進行繼承。在互斥鎖設(shè)置為本協(xié)議屬性情況下,申請互斥鎖時,如果高優(yōu)先級任務(wù)阻塞于互斥鎖,則把持有互斥鎖任務(wù)的優(yōu)先級備份到任務(wù)控制塊的優(yōu)先級位圖中,然后把任務(wù)優(yōu)先級設(shè)置為和高優(yōu)先級任務(wù)相同的優(yōu)先級;持有互斥鎖的任務(wù)釋放互斥鎖時,從任務(wù)控制塊的優(yōu)先級位圖恢復(fù)任務(wù)優(yōu)先級。(3)LOS_MUX_PRIO_PROTECT,該屬性為優(yōu)先級的保護屬性,對申請互斥鎖的任務(wù)的優(yōu)先級進行保護。在互斥鎖設(shè)置為本協(xié)議屬性情況下,申請互斥鎖時,如果任務(wù)優(yōu)先級小于互斥鎖優(yōu)先級上限,則把任務(wù)優(yōu)先級備份到任務(wù)控制塊的優(yōu)先級位圖中,然后把任務(wù)優(yōu)先級設(shè)置為互斥鎖優(yōu)先級上限屬性值;釋放互斥鎖時,從任務(wù)控制塊的優(yōu)先級位圖恢復(fù)任務(wù)優(yōu)先級。安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:LiteOS-A的復(fù)雜屬性基于OpenHarmony的嵌入式開發(fā)17typedefstruct{UINT8protocol;UINT8prioceiling;UINT8type;UINT8reserved;}LosMuxAttr;類型屬性:用于標記是否檢測死鎖和是否支持遞歸持有(1)LOS_MUX_NORMAL,普通互斥鎖,不會檢測死鎖問題。如果任務(wù)試圖對一個互斥鎖重復(fù)持有,將會引起這個線程的死鎖。如果試圖釋放一個由別的任務(wù)持有的互斥鎖,或者如果一個任務(wù)試圖重復(fù)釋放互斥鎖都會引發(fā)不可預(yù)料的結(jié)果。(2)LOS_MUX_RECURSIVE,遞歸互斥鎖,是互斥鎖的默認屬性。允許同一個任務(wù)對互斥鎖進行多次持有鎖,持有鎖次數(shù)和釋放鎖次數(shù)相同,其他任務(wù)才能持有該互斥鎖。如果試圖持有已經(jīng)被其他任務(wù)持有的互斥鎖,或者如果試圖釋放已經(jīng)被釋放的互斥鎖,會返回錯誤碼。(3)LOS_MUX_ERRORCHECK,錯誤檢測互斥鎖,會自動檢測死鎖。在互斥鎖設(shè)置為本類型屬性情況下,如果任務(wù)試圖對一個互斥鎖重復(fù)持有,或者試圖釋放一個由別的任務(wù)持有的互斥鎖,或者如果一個任務(wù)試圖釋放已經(jīng)被釋放的互斥鎖,都會返回錯誤碼。安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:LiteOS-M和LiteOS-A的互斥鎖接口基于OpenHarmony的嵌入式開發(fā)18LiteOS-M接口接口功能說明LOS_MuxPend申請指定的互斥鎖LOS_MuxPost釋放指定的互斥鎖LiteOS-A接口名稱接口功能說明LOS_MuxLock申請指定的互斥鎖LOS_MuxUnlock釋放指定的互斥鎖互斥鎖的申請有三種模式:(1)無阻塞模式:任務(wù)需要申請互斥鎖,若該互斥鎖當(dāng)前沒有任務(wù)持有,或者持有該互斥鎖的任務(wù)和申請該互斥鎖的任務(wù)為同一個任務(wù),則申請成功;(2)永久阻塞模式:任務(wù)需要申請互斥鎖,若該互斥鎖當(dāng)前沒有被占用,則申請成功。否則,該任務(wù)進入阻塞態(tài),系統(tǒng)切換到就緒任務(wù)中優(yōu)先級高者繼續(xù)執(zhí)行。任務(wù)進入阻塞態(tài)后,直到有其他任務(wù)釋放該互斥鎖,阻塞任務(wù)才會重新得以執(zhí)行;(3)定時阻塞模式:任務(wù)需要申請互斥鎖,若該互斥鎖當(dāng)前沒有被占用,則申請成功。否則該任務(wù)進入阻塞態(tài),系統(tǒng)切換到就緒任務(wù)中優(yōu)先級高者繼續(xù)執(zhí)行。任務(wù)進入阻塞態(tài)后,指定時間超時前有其他任務(wù)釋放該互斥鎖,或者用戶指定時間超時后,阻塞任務(wù)才會重新得以執(zhí)行。互斥鎖的釋放有兩種情況:(1)如果有任務(wù)阻塞于指定互斥鎖,則喚醒被阻塞任務(wù)中優(yōu)先級高的,該任務(wù)進入就緒態(tài),并進行任務(wù)調(diào)度;(2)如果沒有任務(wù)阻塞于指定互斥鎖,則互斥鎖釋放成功。安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例(1)任務(wù)Example_TaskEntry創(chuàng)建一個互斥鎖,用于鎖任務(wù)調(diào)度。分別創(chuàng)建了兩個任務(wù)Example_MutexTask1和Example_MutexTask2。其中,Example_MutexTask2的優(yōu)先級高于Example_MutexTask1,然后解鎖任務(wù)調(diào)度。(2)Example_MutexTask2首先被調(diào)度,并以永久阻塞模式申請互斥鎖。該任務(wù)成功獲取到該互斥鎖后,啟動任務(wù)休眠,休眠時間為100Tick,Example_MutexTask2掛起,Example_MutexTask1被喚醒。(3)Example_MutexTask1以定時阻塞模式申請互斥鎖,等待時間為10Tick。但是,因互斥鎖被Example_MutexTask2所持有,Example_MutexTask1會被掛起。當(dāng)10Tick超時時間到達后,Example_MutexTask1被喚醒,再以永久阻塞模式申請互斥鎖,但因互斥鎖仍然被Example_MutexTask2持有,Example_MutexTask1再次被掛起。(4)100Tick的休眠時間到達后,Example_MutexTask2被喚醒,釋放互斥鎖,然后喚醒Example_MutexTask1。Example_MutexTask1成功獲取到互斥鎖后,釋放,刪除互斥鎖?;贠penHarmony的嵌入式開發(fā)19安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例-
Example_MutexTask1基于OpenHarmony的嵌入式開發(fā)20VOIDExample_MutexTask1(VOID){UINT32ret;printf("task1trytogetmutex,wait10ticks.\n");
ret=LOS_MuxLock(&g_testMux,10);
//申請互斥鎖
if(ret==LOS_OK){printf("task1getmutexg_testMux.\n");
LOS_MuxUnlock(&g_testMux);
//釋放互斥鎖
return;
}if(ret==LOS_ETIMEDOUT){printf("task1timeoutandtrytogetmutex,waitforever.\n");
ret=LOS_MuxLock(&g_testMux,LOS_WAIT_FOREVER);
//申請互斥鎖
if(ret==LOS_OK){printf("task1waitforever,getmutexg_testMux.\n");
LOS_MuxUnlock(&g_testMux);
//釋放互斥鎖
LOS_MuxDestroy(&g_testMux);
//刪除互斥鎖
printf("task1postanddeletemutexg_testMux.\n");return;
}}
return;
}安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例-
Example_MutexTask2等基于OpenHarmony的嵌入式開發(fā)21VOIDExample_MutexTask2(VOID){printf("task2trytogetmutex,waitforever.\n");
(VOID)LOS_MuxLock(&g_testMux,LOS_WAIT_FOREVER);
//申請互斥鎖
printf("task2getmutexg_testMuxandsuspend100ticks.\n");
LOS_TaskDelay(100);
//任務(wù)休眠100Ticksprintf("task2resumedandposttheg_testMux\n");
LOS_MuxUnlock(&g_testMux);
//釋放互斥鎖
return;}UINT32Example_MutexEntry(VOID){UINT32ret;TSK_INIT_PARAM_Stask1;TSK_INIT_PARAM_Stask2;
LOS_MuxInit(&g_testMux,NULL);//初始化互斥鎖
LOS_TaskLock();
//鎖任務(wù)調(diào)度
//創(chuàng)建任務(wù)1
……
//創(chuàng)建任務(wù)2
……安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例-
Example_MutexEntry基于OpenHarmony的嵌入式開發(fā)22
//創(chuàng)建任務(wù)1memset(&task1,0,sizeof(TSK_INIT_PARAM_S));
task1.pfnTaskEntry=(TSK_ENTRY_FUNC)Example_MutexTask1;task1.pcName="MutexTsk1";task1.uwStackSize=LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
task1.usTaskPrio=5;
//低優(yōu)先級
ret=LOS_TaskCreate(&g_testTaskId01,&task1);if(ret!=LOS_OK){printf(“task1createfailed.\n”);returnLOS_NOK;
}
//創(chuàng)建任務(wù)2memset(&task2,0,sizeof(TSK_INIT_PARAM_S));
task2.pfnTaskEntry=(TSK_ENTRY_FUNC)Example_MutexTask2;task2.pcName="MutexTsk2";task2.uwStackSize=LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
task2.usTaskPrio=4;
//高優(yōu)先級
ret=LOS_TaskCreate(&g_testTaskId02,&task2);if(ret!=LOS_OK){printf("task2createfailed.\n");returnLOS_NOK;}
LOS_TaskUnlock();
//解鎖任務(wù)調(diào)度
returnLOS_OK;哪個任務(wù)先開始運行?分析一下程序運行結(jié)果安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例-分析運行結(jié)果(均執(zhí)行成功)基于OpenHarmony的嵌入式開發(fā)23Example_MutexEntryret=LOS_TaskCreate(&g_testTaskId01,&task1);
//優(yōu)先級5ret=LOS_TaskCreate(&g_testTaskId02,&task2);
//優(yōu)先級4Example_MutexTask1①
printf("task1trytogetmutex,wait10ticks.\n");②
printf("task1getmutexg_testMux.\n");//如果等待超時③
printf("task1timeoutandtrytogetmutex,waitforever.\n");//如果申請到互斥鎖④
printf("task1waitforever,getmutexg_testMux.\n");//互斥鎖銷毀之后⑤
printf("task1postanddeletemutexg_testMux.\n");Example_MutexTask2⑥
printf("task2trytogetmutex,waitforever.\n");⑦
printf(“task2getmutexg_testMuxandsuspend100ticks.\n”);⑧
printf("task2resumedandposttheg_testMux\n");創(chuàng)建任務(wù)1和任務(wù)2任務(wù)1優(yōu)先級為5任務(wù)2優(yōu)先級為4,優(yōu)先執(zhí)行課堂思考/討論程序運行結(jié)果安全邊距3.1進程間通信[3.1.2]互斥鎖(Mutex)
互斥鎖:互斥鎖的應(yīng)用示例-分析運行結(jié)果(均執(zhí)行成功)基于OpenHarmony的嵌入式開發(fā)24Example_MutexEntryret=LOS_TaskCreate(&g_testTaskId01,&task1);
//優(yōu)先級5ret=LOS_TaskCreate(&g_testTaskId02,&task2);
//優(yōu)先級4Example_MutexTask1printf("task1trytogetmutex,wait10ticks.\n");printf("task1getmutexg_testMux.\n");//如果等待超時printf("task1timeoutandtrytogetmutex,waitforever.\n");//如果申請到互斥鎖printf("task1waitforever,getmutexg_testMux.\n");//互斥鎖銷毀之后printf("task1postanddeletemutexg_testMux.\n");Example_MutexTask2printf("task2trytogetmutex,waitforever.\n");printf(“task2getmutexg_testMuxandsuspend100ticks.\n”);printf("task2resumedandposttheg_testMux\n");程序運行結(jié)果如下task2trytogetmutex,waitforever.task2getmutexg_testMuxandsuspend100ticks.task1trytogetmutex,wait10ticks.task1timeoutandtrytogetmutex,waitforever.task2resumedandposttheg_testMuxtask1waitforever,getmutexg_testMux.task1postanddeletemutexg_testMux.創(chuàng)建任務(wù)1和任務(wù)2任務(wù)1優(yōu)先級為5任務(wù)2優(yōu)先級為4,優(yōu)先執(zhí)行安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列):一種常用于任務(wù)間通信的數(shù)據(jù)結(jié)構(gòu)
隊列接收來自任務(wù)或中斷的不固定長度消息,并根據(jù)不同的接口確定傳遞的消息是否存放在隊列空間中(事件只能傳輸狀態(tài)信息、互斥鎖無法傳輸信息),隊列能夠在任務(wù)之間傳輸更豐富的信息。
任務(wù)能夠從隊列里面讀取消息,當(dāng)隊列中的消息為空時,掛起讀取任務(wù);當(dāng)隊列中有新消息時,掛起的讀取任務(wù)被喚醒并處理新消息。任務(wù)也能夠向隊列中寫入消息,當(dāng)隊列已經(jīng)寫滿消息時,掛起寫入任務(wù);當(dāng)隊列中有空閑消息節(jié)點時,掛起的寫入任務(wù)被喚醒并寫入消息。
可以通過調(diào)整讀隊列和寫隊列的超時時間來調(diào)整讀寫接口的阻塞模式,如果將讀隊列和寫隊列的超時時間設(shè)置為0,就不會掛起任務(wù),接口會直接返回,這就是非阻塞模式。反之,如果將都隊列和寫隊列的超時時間設(shè)置為大于0的時間,就會以阻塞模式運行?;贠penHarmony的嵌入式開發(fā)25安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列):一種常用于任務(wù)間通信的數(shù)據(jù)結(jié)構(gòu)
消息隊列提供了異步處理機制,允許將一個消息放入隊列,但不立即處理,具有異步通信和緩沖作用。隊列具有如下特性。
(1)消息以先進先出的方式排隊,支持異步讀寫。
(2)讀隊列和寫隊列都支持超時機制。
(3)每讀取一條消息,就會將該消息節(jié)點設(shè)置為空閑。
(4)發(fā)送消息類型由通信雙方約定,可以允許不同長度(不超過隊列的消息節(jié)點大小)的消息。
(5)一個任務(wù)能夠與任意一個消息隊列進行消息的接收和發(fā)送消息。
(6)多個任務(wù)能夠從同一個消息隊列接收和發(fā)送消息。
(7)創(chuàng)建隊列時所需的隊列空間,接口內(nèi)系統(tǒng)自行動態(tài)申請內(nèi)存?;贠penHarmony的嵌入式開發(fā)26任務(wù)與消息隊列是多對多的關(guān)系安全邊距3.1進程間通信[3.1.3]隊列(Queue)控制塊:los_queue.h(LiteOS-M)和los_queue_pri.h(LiteOS-A)基于OpenHarmony的嵌入式開發(fā)27typedefstruct{UINT8*queue;
/**<Pointertoaqueuehandle*/UINT16queueState;
/**<Queuestate*/UINT16queueLen;
/**<Queuelength*/UINT16queueSize;
/**<Nodesize*/UINT16queueID;
/**<queueID*/UINT16queueHead;
/**<Nodehead*/UINT16queueTail;
/**<Nodetail*/UINT16readWriteableCnt[OS_READWRITE_LEN];
/**<Countofreadableorwritableresources,0:readable,1:writable*/LOS_DL_LISTreadWriteList[OS_READWRITE_LEN];
/**<Pointertothelinkedlisttobereadorwritten,
0:readlist,
1:writelist*/LOS_DL_LISTmemList;
/**<Pointertothememorylinkedlist*/}LosQueueCB;LiteOS-M隊列控制塊#defineOS_QUEUE_UNUSED
0#defineOS_QUEUE_INUSED
1#defineOS_READWRITE_LEN
2readWriteableCnt[0]表示隊列中可讀消息數(shù),readWriteableCnt[1]表示隊列中可寫消息數(shù)readWriteList[0]表示讀取鏈表readWriteList[1]表示寫入鏈表安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的若干使用基本要點(1)創(chuàng)建隊列時,創(chuàng)建隊列成功會返回隊列ID。(2)在隊列控制塊中維護著一個消息頭節(jié)點位置Head和一個消息尾節(jié)點位置Tail,表示當(dāng)前隊列中消息的存儲情況。Head表示隊列中被占用的消息節(jié)點的起始位置,Tail表示被占用的消息節(jié)點的結(jié)束位置,也是空閑消息節(jié)點的起始位置。隊列創(chuàng)建時Head和Tail均指向起始位置。基于OpenHarmony的嵌入式開發(fā)28安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的若干使用基本要點
(3)在寫隊列時,將根據(jù)readWriteableCnt[1]判斷隊列是否可以寫入,不能對已滿的隊列(readWriteableCnt[1]為0)進行寫操作。寫隊列支持兩種寫入方式:向隊列尾節(jié)點寫入,也可以向隊列頭節(jié)點寫入。尾節(jié)點寫入時,根據(jù)Tail找到起始空閑消息節(jié)點作為數(shù)據(jù)寫入對象,如果Tail已經(jīng)指向隊列尾部則采用回卷方式。頭節(jié)點寫入時,將Head的前一個節(jié)點作為數(shù)據(jù)寫入對象,如果Head指向隊列起始位置則采用回卷方式。(4)在讀隊列時,將根據(jù)readWriteableCnt[0]判斷隊列是否有消息需要讀取,對全部空閑的隊列(readWriteableCnt[0]為0)進行讀操作會引起任務(wù)掛起。如果隊列可以讀取消息,則根據(jù)Head找到最先寫入隊列的消息節(jié)點進行讀取。如果Head已經(jīng)指向隊列尾部則采用回卷方式。(5)在刪除隊列時,根據(jù)隊列ID找到對應(yīng)隊列,把隊列狀態(tài)置為未使用,把隊列控制塊置為初始狀態(tài),并釋放隊列所占內(nèi)存?;贠penHarmony的嵌入式開發(fā)29安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的接口基于OpenHarmony的嵌入式開發(fā)30接口名稱接口功能說明LOS_QueueCreate創(chuàng)建一個消息隊列,由系統(tǒng)動態(tài)申請隊列空間LOS_QueueDelete根據(jù)隊列ID刪除一個指定隊列LOS_QueueRead讀取指定隊列頭節(jié)點中的數(shù)據(jù)(隊列節(jié)點中的數(shù)據(jù)實際上是一個地址)LOS_QueueWrite向指定隊列尾節(jié)點中寫入入?yún)ufferAddr的值(即buffer的地址)LOS_QueueWriteHead向指定隊列頭節(jié)點中寫入入?yún)ufferAddr的值(即buffer的地址)LOS_QueueReadCopy讀取指定隊列頭節(jié)點中的數(shù)據(jù)LOS_QueueWriteCopy向指定隊列尾節(jié)點中寫入入?yún)ufferAddr中保存的數(shù)據(jù)LOS_QueueWriteHeadCopy向指定隊列頭節(jié)點中寫入入?yún)ufferAddr中保存的數(shù)據(jù)LOS_QueueInfoGet獲取指定隊列的信息,包括隊列ID、隊列長度、消息節(jié)點大小、頭節(jié)點、尾節(jié)點、可讀節(jié)點數(shù)量、可寫節(jié)點數(shù)量、等待讀操作的任務(wù)、等待寫操作的任務(wù)安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的開發(fā)示例-基本流程
(1)通過LOS_QueueCreate接口創(chuàng)建隊列,創(chuàng)建成功即可獲得隊列ID;
(2)通過LOS_QueueWrite或者LOS_QueueWriteCopy寫隊列;
(3)通過LOS_QueueRead或者LOS_QueueReadCopy讀隊列;
(4)通過LOS_QueueInfoGet獲取隊列信息;
(5)通過LOS_QueueDelete刪除隊列。隊列(消息隊列)的開發(fā)示例-注意事項
(1)系統(tǒng)支持的最大隊列數(shù)指的是整個系統(tǒng)的隊列資源的總個數(shù),而非用戶能使用的個數(shù)。
(2)創(chuàng)建隊列時傳入的隊列名和flags暫時未使用,作為以后的預(yù)留參數(shù)。
(3)隊列接口函數(shù)中的入?yún)imeOut是相對時間?;贠penHarmony的嵌入式開發(fā)31安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的開發(fā)示例-注意事項(4)LOS_QueueReadCopy和LOS_QueueWriteCopy及LOS_QueueWriteHeadCopy是一組接口,LOS_QueueRead和LOS_QueueWrite及LOS_QueueWriteHead是一組接口,每組接口需要配套使用。
(5)鑒于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead這組接口實際操作的是數(shù)據(jù)地址,用戶必須保證調(diào)用LOS_QueueRead獲取到的指針所指向的內(nèi)存區(qū)域在讀隊列期間沒有被異常修改或釋放,否則可能導(dǎo)致不可預(yù)知的后果。(6)LOS_QueueRead和LOS_QueueReadCopy接口的讀取長度如果小于消息實際長度,消息將被截斷。
(7)鑒于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead這組接口實際操作的是數(shù)據(jù)地址,也就意味著實際寫和讀的消息長度僅僅是一個指針數(shù)據(jù),因此用戶使用這組接口之前,需確保創(chuàng)建隊列時的消息節(jié)點大小,為一個指針的長度,避免不必要的浪費和讀取失敗。基于OpenHarmony的嵌入式開發(fā)32安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的應(yīng)用示例
創(chuàng)建隊列,兩個任務(wù)。任務(wù)1SendEntry調(diào)用寫隊列接口發(fā)送消息,任務(wù)2RecvEntry通過讀隊列接口接收消息。執(zhí)行流程如下。
(1)通過LOS_TaskCreate創(chuàng)建任務(wù)1SendEntry和任務(wù)2RecvEntry。
(2)通過LOS_QueueCreate創(chuàng)建一個消息隊列。
(3)在任務(wù)1SendEntry中發(fā)送消息。
(4)在任務(wù)2RecvEntry中接收消息。
(5)通過LOS_QueueDelete刪除隊列?;贠penHarmony的嵌入式開發(fā)33安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的應(yīng)用示例-
ExampleQueue
基于OpenHarmony的嵌入式開發(fā)34#defineBUFFER_LEN50staticUINT32g_queue;UINT32ExampleQueue(VOID){
……;printf("startqueueexample.\n");
……;initParam.pfnTaskEntry=(TSK_ENTRY_FUNC)SendEntry;
initParam.usTaskPrio=9;
……;LOS_TaskLock();
ret=LOS_TaskCreate(&task1,&initParam);if(ret!=LOS_OK){printf("createtask1failed,error:%x\n",ret);returnret;}……;initParam.pfnTaskEntry=(TSK_ENTRY_FUNC)RecvEntry;initParam.usTaskPrio=10;
ret=LOS_TaskCreate(&task2,&initParam);if(ret!=LOS_OK){printf("createtask2failed,error:%x\n",ret);returnret;}
ret=LOS_QueueCreate("queue",5,&g_queue,0,50);if(ret!=LOS_OK){printf("createqueuefailure,error:%x\n",ret);}printf("createthequeuesuccess.\n");LOS_TaskUnlock();returnret;}externUINT32LOS_QueueCreate(constCHAR*queueName,UINT16len,UINT32*queueID,UINT32flags,UINT16maxMsgSize);安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的應(yīng)用示例-
SendEntry和RecvEntry
基于OpenHarmony的嵌入式開發(fā)35VOIDSendEntry(VOID){UINT32ret=0;CHARabuf[]="testmessage";UINT32len=sizeof(abuf);
ret=LOS_QueueWriteCopy(g_queue,abuf,len,0);if(ret!=LOS_OK){printf("sendmessagefailure,error:%x\n",ret);}}VOIDRecvEntry(VOID){UINT32ret=0;CHARreadBuf[BUFFER_LEN]={0};UINT32readLen=BUFFER_LEN;usleep(1000000);
ret=LOS_QueueReadCopy(g_queue,readBuf,&readLen,0);if(ret!=LOS_OK){printf("recvmessagefailure,error:%x\n",ret);}printf("recvmessage:%s\n",readBuf);ret=LOS_QueueDelete(g_queue);if(ret!=LOS_OK){printf("deletethequeuefailure,error:%x\n",ret);}printf("deletethequeuesuccess.\n");}externUINT32LOS_QueueWriteCopy(UINT32queueID,VOID*bufferAddr,
UINT32bufferSize,UINT32timeOut);externUINT32LOS_QueueReadCopy(UINT32queueID,VOID*bufferAddr,
UINT32*bufferSize,UINT32timeOut);安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的應(yīng)用示例-
SendEntry和RecvEntry
基于OpenHarmony的嵌入式開發(fā)36SendEntryret=LOS_QueueWriteCopy(g_queue,abuf,len,0);RecvEntryret=LOS_QueueReadCopy(g_queue,readBuf,
&readLen,0);//接收數(shù)據(jù)成功后printf("recvmessage:%s\n",readBuf);ret=LOS_QueueDelete(g_queue);//刪除隊列成功后printf("deletethequeuesuccess.\n");ExampleQueueprintf("startqueueexample.\n");ret=LOS_TaskCreate(&task1,&initParam);
//優(yōu)先級9ret=LOS_TaskCreate(&task2,&initParam);
//優(yōu)先級10ret=LOS_QueueCreate("queue",5,&g_queue,0,50);printf("createthequeuesuccess.\n");創(chuàng)建任務(wù)1和任務(wù)2任務(wù)1優(yōu)先級為9(高),優(yōu)先執(zhí)行任務(wù)2優(yōu)先級為10(低)課堂思考/討論程序運行結(jié)果安全邊距3.1進程間通信[3.1.3]隊列(Queue)隊列(消息隊列)的應(yīng)用示例-
SendEntry和RecvEntry
基于OpenHarmony的嵌入式開發(fā)37SendEntryret=LOS_QueueWriteCopy(g_queue,abuf,len,0);RecvEntryret=LOS_QueueReadCopy(g_queue,readBuf,
&readLen,0);//接收數(shù)據(jù)成功后printf("recvmessage:%s\n",readBuf);ret=LOS_QueueDelete(g_queue);//刪除隊列成功后printf("deletethequeuesuccess.\n");ExampleQueueprintf("startqueueexample.\n");ret=LOS_TaskCreate(&task1,&initParam);
//優(yōu)先級9ret=LOS_TaskCreate(&task2,&initParam);
//優(yōu)先級10ret=LOS_QueueCreate("queue",5,&g_queue,0,50);printf("createthequeuesuccess.\n");創(chuàng)建任務(wù)1和任務(wù)2任務(wù)1優(yōu)先級為9(低)任務(wù)2優(yōu)先級為10(高),優(yōu)先執(zhí)行程序運行結(jié)果如下startqueueexample.createthequeuesuccess.recvmessage:testmessage.deletethequeuesuccess.安全邊距3.1進程間通信[3.1.4]信號量(Semaphore)
信號量(Semaphore)又稱信號燈,是一種實現(xiàn)任務(wù)間通信的機制,可以實現(xiàn)任務(wù)間同步或共享資源的互斥訪問。
在信號量的數(shù)據(jù)結(jié)構(gòu)中,通常有一個計數(shù)值,用于對有效資源數(shù)的計數(shù),表示剩下的可被使用的共享資源數(shù),其值的含義分兩種情況。
(1)0,表示該信號量當(dāng)前不可獲取,因此可能存在正在等待該信號量的任務(wù)。
(2)正值,表示該信號量當(dāng)前可被獲取。基于OpenHarmony的嵌入式開發(fā)38初始信號量計數(shù)值不為0,表示可用的共享資源個數(shù)。在需要使用共享資源前,先獲取信號量,然后使用一個共享資源,使用完畢后釋放信號量。這樣在共享資源被取完,即信號量計數(shù)減至0時,其他需要獲取信號量的任務(wù)將被阻塞,從而保證了共享資源的互斥訪問。另外,當(dāng)共享資源數(shù)為1時,建議使用二值信號量,一種類似于互斥鎖的機制。初始信號量計數(shù)值為0。任務(wù)1因獲取不到信號量而阻塞,直到任務(wù)2或者某中斷釋放信號量,任務(wù)1才得以進入Ready或Running態(tài),從而達到了任務(wù)間的同步。安全邊距3.1進程間通信[3.1.4]信號量(Semaphore)控制塊:基于OpenHarmony的嵌入式開發(fā)39/***@ingrouplos_sem*Semaphorecontrolstructure.*/typedefstruct{
/**<Semaphorestate*/
UINT16semStat;
/**<Numberofavailablesemaphores*/
UINT16semCount;
/**<Maxnumberofavailablesemaphores*/UINT16maxSemCount;
/**<SemaphorecontrolstructureID*/
UINT16semID;
/**<Queueoftasksthatarewaitingonasemaphore*/LOS_DL_LISTsemList;}LosSemCB;LiteOS-M/LiteoS-A信號量控制塊#defineOS_SEM_UNUSED0#defineOS_SEM_USED1安全邊距3.1進程間通信[3.1.4]信號量(Semaphore)運行原理:多個任務(wù)在同一時刻訪問共享資源,但會限制同一時刻訪問此資源的最大任務(wù)數(shù)目。當(dāng)任務(wù)數(shù)達到該資源允許的最大訪問數(shù)量時,會阻塞其他試圖獲取該資源的任務(wù),直到有任務(wù)釋放該信號量。基于OpenHarmony的嵌入式開發(fā)40注意:與互斥鎖的區(qū)別安全邊距3.1進程間通信[3.1.4]信號量(Semaphore)信號量的接口基于OpenHarmony的嵌入式開發(fā)41接口名稱接口功能說明LOS_SemCreateLOS_BinarySemCreate創(chuàng)建信號量或二值信號量,返回信號量ID。從未使用的信號量鏈表中獲取一個信號量,并設(shè)定初值。LOS_SemDelete刪除指定的信號量。將正在使用的信號量置為未使用信號量,并掛回到未使用鏈表。LOS_SemPend申請指定的信號量,并設(shè)置超時時間。若其計數(shù)器值大于0,則直接減1返回成功。否則任務(wù)阻塞,等待其它任務(wù)釋放該信號量,等待的超時時間可設(shè)定。當(dāng)任務(wù)被一個信號量阻塞時,將該任務(wù)掛到信號量等待任務(wù)隊列的隊尾。LOS_SemPost釋放指定的信號量。若沒有任務(wù)等待該信號量,則直接將計數(shù)器加1返回。否則喚醒該信號量等待任務(wù)隊列上的第一個任務(wù)。安全邊距3.1進程間通信[3.1.4]信號量(Semaphore)信號量的的應(yīng)用示例:ExampleSem創(chuàng)建一個信號量,鎖任務(wù)調(diào)度。然后創(chuàng)建兩個任務(wù)ExampleSemTask1和ExampleSemTask2,其中,ExampleSemTask2的優(yōu)先級高于ExampleSemTask1。兩個任務(wù)申請同一信號量,解鎖任務(wù)調(diào)度后,測試任務(wù)ExampleSem釋放信號量。
(1)ExampleSemTask2得到信號量后被調(diào)度,然后
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025中鐵國資資產(chǎn)管理有限公司招聘3人筆試參考題庫附帶答案詳解
- 2025中盛遠創(chuàng)建設(shè)集團有限公司招聘筆試參考題庫附帶答案詳解
- 2025中核集團原子能院校園招聘筆試參考題庫附帶答案詳解
- 2025中好建造(安徽)科技有限公司第二次社會招聘13人筆試參考題庫附帶答案詳解
- 2025中國鐵塔山東德州市分公司校園招聘(1人)筆試歷年??键c試題專練附帶答案詳解2套試卷
- 2025中國石化銷售股份有限公司應(yīng)用技術(shù)研究院社會成熟人才公開招聘6人(天津)筆試參考題庫附帶答案詳解
- 2025中國煤炭地質(zhì)總局新媒體中心招聘1人筆試參考題庫附帶答案詳解
- 2025中國旅游集團所屬企業(yè)崗位招聘4人筆試歷年典型考點題庫附帶答案詳解2套試卷
- 2025中國建材集團有限公司所屬企業(yè)招聘15人筆試參考題庫附帶答案詳解
- 2025中國大唐集團科技創(chuàng)新有限公司招聘筆試歷年備考題庫附帶答案詳解
- 露天礦山安全生產(chǎn)崗位責(zé)任制與制度匯編
- 公司生產(chǎn)質(zhì)量獎罰制度
- 綜采隊檢修生產(chǎn)考核制度
- 第23課 醫(yī)療設(shè)施新功能 課件 2025-2026學(xué)年人教版初中信息科技八年級全一冊
- 2025年煙臺汽車工程職業(yè)學(xué)院單招綜合素質(zhì)考試題庫附答案解析
- GB 12801-2025生產(chǎn)過程安全基本要求
- 2026屆重慶市普通高中英語高三第一學(xué)期期末統(tǒng)考試題含解析
- 合同福利模板范文(3篇)
- 中醫(yī)綜合專升本課件
- DB32∕T 5124.3-2025 臨床護理技術(shù)規(guī)范 第3部分:成人危重癥患者有創(chuàng)動脈血壓監(jiān)測
- 《烹飪原料學(xué)》烹飪專業(yè)高職全套教學(xué)課件
評論
0/150
提交評論