Windows程序的執(zhí)行單元_第1頁
Windows程序的執(zhí)行單元_第2頁
Windows程序的執(zhí)行單元_第3頁
Windows程序的執(zhí)行單元_第4頁
Windows程序的執(zhí)行單元_第5頁
已閱讀5頁,還剩47頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第3章Windows程序的執(zhí)行單元——線程Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第1頁!3.1多線程線程的創(chuàng)建線程內(nèi)核對象線程的終止線程的優(yōu)先級C/C++運行期庫Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第2頁!線程的創(chuàng)建多線程并發(fā)執(zhí)行,os為其輪流分配cpu時間片一般情況,主線程接受用戶輸入,顯示運行結(jié)果;新創(chuàng)建的線程來處理長時間的操作,如讀寫文件、訪問網(wǎng)絡(luò)等,這樣即便程序忙于繁重的工作也可以由專門的線程響應(yīng)用戶命令每個線程必須擁有入口點函數(shù),主線程的為main。輔助線程入口點函數(shù)稱為線程函數(shù),定義如下:DWORDWINAPIThreadProc(LPVOIDlpParam);

函數(shù)名稱ThreadProc可以是任意的Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第3頁!線程的創(chuàng)建創(chuàng)建新線程用CreateThreadHANDLE

CreateThread(

LPSECURITY_ATTRIBUTES

lpsa,DWORD

cbStack,LPTHREAD_START_ROUTINE

lpStartAddr,LPVOID

lpvThreadParam,DWORD

fdwCreate, LPDWORD

lpIDThread

);

Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第4頁!WaitForSingleObjectDWORD

WaitForSingleObject(HANDLE

hHandle,DWORD

dwMilliseconds

);

Thisfunctionreturnswhenthespecifiedobjectisinthesignaledstate(受信狀態(tài))orwhenthetime-outintervalelapses.該函數(shù)用于等待指定的對象(hHandle)變成受信狀態(tài)。 說明:在例03ThreadDemo工程中,用于等待輔助線程對應(yīng)的函數(shù)ThreadProc()執(zhí)行完成。調(diào)用該函數(shù)將阻塞主線程。一個可執(zhí)行對象有兩種狀態(tài):未受信、受信。線程對象只有當線程結(jié)束才為受信態(tài)。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第5頁!線程的創(chuàng)建例子程序Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第6頁!2.線程創(chuàng)建例子中使用計數(shù)調(diào)用CreateThread后,使用計數(shù)=2,線程函數(shù)返回,系統(tǒng)將使使用計數(shù)減少1,即使用計數(shù)=1,接下來又調(diào)用CloseHandle使使用計數(shù)減1,即最后使用計數(shù)=0,該內(nèi)存空間被收回。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第7頁!3.1.3線程的終止線程終止的4種方法線程函數(shù)自然退出ExitThreadTerminateThread造成無法作清除工作,ExitProcess不提倡例子程序02ExitThreadWindows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第8頁!THREAD_PRIORITY_TIME_CRITICAL實時THREAD_PRIORITY_HIGHEST最高THREAD_PRIORITY_ABOVE_NORMAL高于正常THREAD_PRIORITY_NORMAL正常THREAD_PRIORITY_BELOW_NORMAL低于正常THREAD_PRIORITY_LOWEST最低THREAD_PRIORITY_ABOVE_IDLE高于最低THREAD_PRIORITY_IDLE空閑Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第9頁!3.1.5C/C++運行期庫在實際的開發(fā)過程中,一般使用c/c++運行期函數(shù)_beginthreadx代替CreateThread函數(shù)。_beginthreadx首先申請一些用于線程同步的變量,然后調(diào)用CreateThreadVc++默認的c/c++運行期庫不支持_beginthreadx,需要設(shè)置”Project/settings/c/c++/codegeneration/…./選中multithreadDLL”即可。需要#include<process.h>同樣,使用_endthreadex代替ExitThread。該函數(shù)首先釋放用于線程同步的變量,再調(diào)用ExitThreadWindows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第10頁!3.2線程同步解決同步問題的方法:臨界區(qū)對象:線程獨占,等待的線程掛起,不可調(diào)度互鎖函數(shù):單一變量同步問題事件內(nèi)核對象:是否”受信”,通知信號量內(nèi)核對象:信號量計數(shù),多個線程共享,用于Socket(套接字)程序中線程同步互斥內(nèi)核對象:線程獨占,等待的線程可調(diào)度,用于保護內(nèi)存Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第11頁!3.2.1臨界區(qū)對象1.為什么要線程同步?多線程同步要能保證在一個線程占有公共資源的時候,其他線程不會再占有這個資源。解決同步問題,就要保證整個存取過程的獨占性。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第12頁!使用臨界區(qū)對象void

InitializeCriticalSection(LPCRITICAL_SECTION

lpCriticalSection

);

ParameterslpCriticalSection

[in]Pointertothecriticalsectionobject.初始化臨界區(qū)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第13頁!使用臨界區(qū)對象void

LeaveCriticalSection(LPCRITICAL_SECTION

lpCriticalSection

);

ParameterslpCriticalSection

[in]Pointertothecriticalsectionobject.將臨界區(qū)交還給Windows,離開臨界區(qū)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第14頁!使用臨界區(qū)對象使用方法說明及程序例子03CriticalSection臨界區(qū)對象能夠很好的保護共享數(shù)據(jù),但是它不能夠用于進程之間資源的鎖定,因為它不是內(nèi)核對象,如果要在進程間維持線程的同步,可以使用事件內(nèi)核對象。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第15頁!互鎖函數(shù)TheInterlockedIncrementfunctionincrements(increasesbyone)thevalueofthespecified32-bitvariableandcheckstheresultingvalue.Thefunctionpreventsmorethanonethreadfromusingthesamevariablesimultaneously.程序例子03InterlockDemoWindows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第16頁!3.2.3事件內(nèi)核對象事件內(nèi)核對象主要用于線程間通信(同步就是一種簡單的通信,指通信的數(shù)據(jù)量少)因為它是一個內(nèi)核對象,所以可以跨進程使用,依靠通信,使各線程的工作協(xié)調(diào)進行,達到同步的目的。事件內(nèi)核對象包括3個成員nUsageCount(使用計數(shù))bManualReset(是否人工重置)bSignaled(是否受信)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第17頁!事件內(nèi)核對象設(shè)置事件對象名稱是為了在其他地方(如:其他進程的線程中)使用OpenEvent或者CreateEvent獲得此內(nèi)核對象句柄。HANDLEOpenEvent(DWORDdwDesiredAccess,訪問權(quán)限

BOOLbInheritHandle,句柄是否被繼承

LPCTSTRlpName);

事件對象名稱Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第18頁!事件內(nèi)核對象說明當一個自動重置的事件對象受信以后,windows僅允許一個等待在該事件上的線程變?yōu)榭烧{(diào)度狀態(tài),然后就自動重置此事件對象為未受信狀態(tài)。(如果使用setevent,則上述動作是緊接著setevent進行,然后才執(zhí)行setevent后面的代碼)當一個人工重置事件對象受信后,所有等待在該對象上的線程都變?yōu)榭烧{(diào)度狀態(tài)。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第19頁!//放蘋果

UINTWINAPIPutAppleThread(PVOIDpvParam)

{

for(inti=0;i<10;i++)

{

WaitForSingleObject(g_dish,INFINITE);

WaitForSingleObject(g_putApple,INFINITE);

cout<<"putapple!\n";

SetEvent(g_eatApple);

Sleep(5);

}

return0;

}Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第20頁!//吃蘋果

UINTWINAPIEatAppleThread(PVOIDpvParam)

{

for(inti=0;i<10;i++)

{

WaitForSingleObject(g_eatApple,INFINITE);

cout<<"eatapple!\n";

SetEvent(g_putApple);

SetEvent(g_dish);;

}

return0;

}Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第21頁!intmain()

{

g_putApple=CreateEvent(NULL,FALSE,TRUE,NULL);

g_putBanana=CreateEvent(NULL,FALSE,TRUE,NULL);

g_eatApple=CreateEvent(NULL,FALSE,FALSE,NULL);

g_eatBanana=CreateEvent(NULL,FALSE,FALSE,NULL);

g_dish=CreateEvent(NULL,FALSE,TRUE,NULL);

HANDLEhThread[4];

intx;

hThread[0]=(HANDLE)_beginthreadex(NULL,0,PutAppleThread,(void*)&x,0,NULL);

hThread[1]=(HANDLE)_beginthreadex(NULL,0,PutBananaThread,(void*)&x,0,NULL);

hThread[2]=(HANDLE)_beginthreadex(NULL,0,EatAppleThread,(void*)&x,0,NULL);

hThread[3]=(HANDLE)_beginthreadex(NULL,0,EatBananaThread,(void*)&x,0,NULL);

charch;

cin>>ch;

return0;

}Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第22頁!線程局部存儲(TLS)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第23頁!線程局部存儲(TLS)

系統(tǒng)為每一個進程都維護著一個長度為TLS_MINIMUM_AVAILABLE的位數(shù)組,TlsAlloc的返回值就是數(shù)組的一個下標(索引)。這個位數(shù)組的惟一用途就是記憶哪一個下標在使用中。初始狀態(tài)下,此位數(shù)組成員的值都是FREE,表示未被使用。當調(diào)用TlsAlloc的時候,系統(tǒng)會挨個檢查這個數(shù)組中成員的值,直到找到一個值為FREE的成員。把找到的成員的值由FREE改為INUSE后,TlsAlloc函數(shù)返回該成員的索引。如果不能找到一個值為FREE的成員,TlsAlloc函數(shù)就返回TLS_OUT_OF_INDEXES(在WinBase.h文件中定義為-1),意味著失敗。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第24頁!線程局部存儲(TLS)TlsSetValue和TlsGetValue分別用于設(shè)置和取得線程數(shù)組中的特定成員的值,而它們使用的索引就是TlsAlloc函數(shù)的返回值。這就充分說明了進程中惟一的位數(shù)組和各線程數(shù)組的關(guān)系。例如,TlsAlloc返回3,那就說明索引3被此進程中的每一個正在運行的和以后要被創(chuàng)建的線程保存起來,用以訪問各自線程數(shù)組中對應(yīng)的成員的值。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第25頁!線程局部存儲(TLS)程序例子Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第26頁!classCRapidFinder{public: CRapidFinder(intnMaxThread); virtual~CRapidFinder(); BOOLCheckFile(LPCTSTRlpszFileName); intm_nResultCount; //結(jié)果數(shù)目

intm_nThreadCount; //活動線程數(shù)目

CTypedSimpleList<CDirectoryNode*>m_listDir;//

目錄列表

CRITICAL_SECTIONm_cs; //關(guān)鍵代碼段

constintm_nMaxThread; //最大線程數(shù)目

charm_szMatchName[MAX_PATH]; //要搜索的文件

HANDLEm_hDirEvent; //向m_listDir中添加新的目 錄后置位(受信)

HANDLEm_hExitEvent; //各搜索線程將要退出時置位 (受信)};Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第27頁!線程的創(chuàng)建#defineWINAPI_stdcall;_stdcall是新標準c/c++調(diào)用方法,與標準c調(diào)用_cdecl相比,參數(shù)進棧次序相同,從右到左,但_stdcall采用自動清棧方式,而_cdecl采用手工清棧方式。由windows操作系統(tǒng)調(diào)用的函數(shù)(回調(diào)函數(shù))必須聲明為_stdcall沒有顯示說明的話,為_cdecl調(diào)用方式Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第28頁!線程的創(chuàng)建lpsa

[in]Ignored.MustbeNULL.指定線程安全屬性cbStack

[in]指定線程堆棧大小,NULL為默認大小lpStartAddr

[in]線程函數(shù)起始地址lpvThreadParam

[in]Longpointertoasingle32-bitparametervaluepassedtothethread.fdwCreate

[in]Specifiesflagsthatcontrolthecreationofthethread.0表示線程創(chuàng)建后立即運行l(wèi)pIDThread

[out]Longpointertoa32-bitvariablethatreceivesthethreadidentifier.IfthisparameterisNULL,thethreadidentifierisnotreturned.Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第29頁!WaitForSingleObjecthHandle

[in]Handletotheobject.Foralistoftheobjecttypeswhosehandlescanbespecified,seetheRemarkssection.dwMilliseconds

[in]Specifiesthetime-outinterval,inmilliseconds.Thefunctionreturnsiftheintervalelapses,eveniftheobject'sstateisnonsignaled.IfdwMillisecondsiszero,thefunctionteststheobject'sstateandreturnsimmediately.IfdwMillisecondsisINFINITE,thefunction'stime-outintervalneverelapses.Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第30頁!3.1.2線程內(nèi)核對象線程內(nèi)核對象是一個包含了線程狀態(tài)信息的數(shù)據(jù)結(jié)構(gòu)。每次對CreateThread的成功調(diào)用,系統(tǒng)都會在內(nèi)部為新的線程分配一個內(nèi)核對象。系統(tǒng)對線程的管理是依靠訪問線程內(nèi)核對象來實現(xiàn)的。1.線程上下文CONTEXT反映該線程上次運行時CPU寄存器的狀態(tài)。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第31頁!CONTEXT(上下文,即寄存器的狀態(tài)),恢復現(xiàn)場必須使用使用計數(shù)(2):CreateThread返回句柄,相當于打開一次內(nèi)核對象,促使該值+1,所以初始值=2;另外,OpenThread使該值+1,GetCurrentThread不會改變該值暫停次數(shù)(1):1表示處于暫停狀態(tài),這樣就不會被調(diào)度到CPU中,給CreateThread時間對線程進行初始化。初始化之后,如果未傳遞CREATE_SUSPENDED(掛起)標志,暫停次數(shù)=0,該線程處于可調(diào)度狀態(tài)。喚醒用ResumeThread(),該函數(shù)使暫停次數(shù)-1,掛起用SuspendThread(),該函數(shù)使暫停次數(shù)+1,一個線程可以被掛起若干次,這就需要喚醒同樣次數(shù)才能使暫停次數(shù)=0,才能處于可調(diào)度狀態(tài),大約每隔20ms,進行一次時間片輪轉(zhuǎn),os選擇新線程,將其上下文裝入cpu寄存器,組織起運行。退出代碼(STILL_ALIVE):即線程函數(shù)的返回值,可以用GetExitCodeThread得到線程退出代碼,所以可以當作自定義的返回值來表示線程的執(zhí)行結(jié)果。是否受信(FALSE):只有當線程結(jié)束時,該值才為TRUE…Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第32頁!3.1.4線程的優(yōu)先級每個線程被賦予一個優(yōu)先級號,0——31,0最低,31最高,調(diào)度時選擇最高的,并采用搶占式優(yōu)先調(diào)度算法。eg:IEexplor的線程優(yōu)先級就很高。設(shè)置優(yōu)先級用SetThreadPriority()。BOOL

SetThreadPriority(HANDLE

hThread,int

nPriority

);

Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第33頁!線程的優(yōu)先級例子程序Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第34頁!3.2線程同步同步可以保證在一個時間內(nèi)只有一個線程對某個共享資源有控制權(quán)。臨界區(qū)對象事件內(nèi)核對象線程局部存儲(TLS)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第35頁!3.2.1臨界區(qū)對象1.為什么要線程同步?當多個線程在同一個進程中執(zhí)行時,可能有不止一個線程同時執(zhí)行同一段代碼,訪問同一段內(nèi)存中的數(shù)據(jù)。線程同步產(chǎn)生的問題——一個錯誤的例子03ConntErr→線程函數(shù)ThreadFunc同時增加全局變量g_nCount1和g_nConnt2的計數(shù),原則上兩個變量的值應(yīng)該相等,但由于是兩個線程同時訪問這兩個全局變量,最終g_nCount1和g_nConnt2的值卻不相等。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第36頁!2.使用臨界區(qū)對象臨界區(qū)對象是定義在數(shù)據(jù)段中的一個CRITICAL_SECTION結(jié)構(gòu),Windows內(nèi)部使用這個結(jié)構(gòu)紀錄一些同步信息,確保在同一時間只有一個線程訪問該數(shù)據(jù)段中的數(shù)據(jù)。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第37頁!使用臨界區(qū)對象void

EnterCriticalSection(LPCRITICAL_SECTION

lpCriticalSection

);

ParameterslpCriticalSection

[in]Pointertothecriticalsectionobject.申請進入臨界區(qū)Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第38頁!使用臨界區(qū)對象void

DeleteCriticalSection(LPCRITICAL_SECTION

lpCriticalSection

);

ParameterslpCriticalSection

[in]Pointertothecriticalsectionobject.整個程序不再使用臨界區(qū)的時候,將臨界區(qū)刪除Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第39頁!3.2.2互鎖函數(shù)互鎖函數(shù)為同步訪問多線程共享變量提供了一個簡單的機制。如果變量在共享內(nèi)存,不同進程的線程也可以使用此機制?;ユi函數(shù)包括:InterlockedIncrementInterlockedDecrementInterlockedExchangeAddInterlockedExchangePointerWindows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第40頁!while(g_bContinue) { ::InterlockedIncrement((long*)&g_nCount1); ::InterlockedIncrement((long*)&g_nCount2); }在主線程中等待子線程的結(jié)束,子線程的結(jié)束條件是g_bContinue=false,這就保證了在一個子線程中,g_nCount1和g_nCount2執(zhí)行了相同多次。產(chǎn)生不一致的唯一原因是加1的操作被打斷Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第41頁!事件內(nèi)核對象使用WaitForSingleObject來判斷事件內(nèi)核對象是否受信,來達到通信的目的。使用CreateEvent函數(shù)創(chuàng)建事件對象。HANDLE

CreateEvent(

LPSECURITY_ATTRIBUTES

lpEventAttributes,安全屬性

BOOL

bManualReset,是否手動重置

BOOL

bInitialState,初始狀態(tài)

LPTSTR

lpName

);

事件對象名稱Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第42頁!事件內(nèi)核對象BOOL

SetEvent(

HANDLE

hEvent

);

將事件對象狀態(tài)設(shè)置為“受信”BOOL

ResetEvent(HANDLEhEvent

);

將事件對象狀態(tài)設(shè)置為“未受信”程序例子Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第43頁!線程同步問題實例問題描述:**********************************

*父親放蘋果,兒子吃蘋果,母親放香蕉,女兒吃香蕉

*在一個盤子之中只能放一樣水果,蘋果或香蕉

**********************************創(chuàng)建4個線程,分別代表父親、兒子、母親和女兒。主線程做初始化和收尾工作Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第44頁!//放香蕉

UINTWINAPIPutBananaThread(PVOIDpvParam)

{

for(inti=0;i<10;i++)

{

WaitForSingleObject(g_dish,INFINITE);

WaitForSingleObject(g_putBanana,INFINITE);

cout<<"putbanana!\n";

SetEvent(g_eatBanana);

Sleep(5);

}

return0;

}Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第45頁!//吃香蕉

UINTWINAPIEatBananaThread(PVOIDpvParam)

{

for(inti=0;i<10;i++)

{

WaitForSingleObject(g_eatBanana,INFINITE);

cout<<"eatbanana!\n";

SetEvent(g_putBanana);

SetEvent(g_dish);

}

return0;

}Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第46頁!3.2.6線程局部存儲(TLS)線程局部存儲(thread-localstorage,TLS)是一個使用很方便的存儲線程局部數(shù)據(jù)的系統(tǒng)。利用TLS機制可以為進程中所有的線程關(guān)聯(lián)若干個數(shù)據(jù),各個線程通過由TLS分配的全局索引來訪問與自己關(guān)聯(lián)的數(shù)據(jù)。這樣,每個線程都可以有線程局部的靜態(tài)存儲數(shù)據(jù)。Windows程序的執(zhí)行單元共52頁,您現(xiàn)在瀏覽的是第47頁!線程局部存儲(TLS)動態(tài)使用TLS的典型步驟如下。(1)主線程調(diào)用TlsAlloc函

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論