青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

思勤無邪

上學時,因我年齡最小,個頭也最小,上課時,就像大猩猩堆里的猴一般。如今,這猴偶爾也把最近的一些情況寫在這里。

   :: 首頁 :: 聯系 :: 聚合  :: 管理
  132 Posts :: 1 Stories :: 178 Comments :: 0 Trackbacks

公告

     吾日常三省吾身,曰思、曰勤、曰無邪。

積分與排名

  • 積分 - 187701
  • 排名 - 140

最新隨筆

最新評論

閱讀排行榜

評論排行榜

 

  進程

  進程是當前操作系統下一個被加載到內存的、正在運行的應用程序的實例。每一個進程都是由內核對象和地址空間所組成的,內核對象可以讓系統在其內存放有關進程的統計信息并使系統能夠以此來管理進程,而地址空間則包括了所有程序模塊的代碼和數據以及線程堆棧、堆分配空間等動態分配的空間。進程僅僅是一個存在,是不能獨自完成任何操作的,必須擁有至少一個在其環境下運行的線程,并由其負責執行在進程地址空間內的代碼。在進程啟動的同時即同時啟動了一個線程,該線程被稱作主線程或是執行線程,由此線程可以繼續創建子線程。如果主線程退出,那么進程也就沒有存在的可能了,系統將自動撤消該進程并完成對其地址空間的釋放。

  加載到進程地址空間的每一個可執行文件或動態鏈接庫文件的映象都會被分配一個與之相關聯的全局唯一的實例句柄( Hinstance )。該實例句柄實際是一個記錄有進程加載位置的基本內存地址。進程的實例句柄在程序入口函數 WinMain ()中通過第一個參數 HINSTANCE hinstExe 傳遞,其實際值即為進程所使用的基本地址空間的地址。對于 VC++ 鏈接程序所鏈接產生的程序,其默認的基本地址空間地址為 0x00400000 ,如沒有必要一般不要修改該值。在程序中,可以通過 GetModuleHandle ()函數得到指定模塊所使用的基本地址空間。

  子進程的創建

  進程的創建通過 CreateProcess ()函數來實現, CreateProcess ()通過創建一個新的進程及在其地址空間內運行的主線程來啟動并運行一個新的程序。具體的,在執行 CreateProcess ()函數時,首先由操作系統負責創建一個進程內核對象,初始化計數為 1 ,并立即為新進程創建一塊虛擬地址空間。隨后將可執行文件或其他任何必要的動態鏈接庫文件的代碼和數據裝載到該地址空間中。在創建主線程時,也是首先由系統負責創建一個線程內核對象,并初始化為 1 。最后啟動主線程并執行進程的入口函數 WinMain (),完成對進程和執行線程的創建。

   CreateProcess ()函數的原型聲明如下:

BOOL CreateProcess(

  LPCTSTR lpApplicationName, // 可執行模塊名

  LPTSTR lpCommandLine, // 命令行字符串

  LPSECURITY_ATTRIBUTES lpProcessAttributes, // 進程的安全屬性

  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 線程的安全屬性

  BOOL bInheritHandles, // 句柄繼承標志

  DWORD dwCreationFlags, // 創建標志

  LPVOID lpEnvironment, // 指向新的環境塊的指針

  LPCTSTR lpCurrentDirectory, // 指向當前目錄名的指針

  LPSTARTUPINFO lpStartupInfo, // 指向啟動信息結構的指針

  LPPROCESS_INFORMATION lpProcessInformation // 指向進程信息結構的指針

);

  在程序設計時,某一個具體的功能模塊可以通過函數或是線程等不同的形式來實現。對于同一進程而言,這些函數、線程都是存在于同一個地址空間下的,而且在執行時,大多只對與其相關的一些數據進行處理。如果算法存在某種錯誤,將有可能破壞與其同處一個地址空間的其他一些重要內容,這將造成比較嚴重的后果。為保護地址空間中的內容可以考慮將那些需要對地址空間中的數據進行訪問的操作部分放到另外一個進程的地址空間中運行,并且只允許其訪問原進程地址空間中的相關數據。具體的,可在進程中通過 CreateProcess ()函數去創建一個子進程,子進程在全部處理過程中只對父進程地址空間中的相關數據進行訪問,從而可以保護父進程地址空間中與當前子進程執行任務無關的全部數據。對于這種情況,子進程所體現出來的作用同函數和線程比較相似,可以看成是父進程在運行期間的一個過程。為此,需要由父進程來掌握子進程的啟動、執行和退出。下面這段代碼即展示了此過程:

// 臨時變量

CString sCommandLine;

char cWindowsDirectory[MAX_PATH];

char cCommandLine[MAX_PATH];

DWORD dwExitCode;

PROCESS_INFORMATION pi;

STARTUPINFO si = {sizeof(si)};

// 得到 Windows 目錄

GetWindowsDirectory(cWindowsDirectory, MAX_PATH);

// 啟動 " 記事本 " 程序的命令行

sCommandLine = CString(cWindowsDirectory) + "\\NotePad.exe";

::strcpy(cCommandLine, sCommandLine);

// 啟動 " 記事本 " 作為子進程

BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

if (ret) {

  // 關閉子進程的主線程句柄

  CloseHandle(pi.hThread);

  // 等待子進程的退出

  WaitForSingleObject(pi.hProcess, INFINITE);

  // 獲取子進程的退出碼

  GetExitCodeProcess(pi.hProcess, &dwExitCode);

  // 關閉子進程句柄

  CloseHandle(pi.hProcess);

}

  此段代碼首先通過 CreateProcess ()創建 Windows 自帶的 記事本 程序為子進程,子進程啟動后父進程通過 WaitForSingleObject ()函數等待其執行的結束,在子進程沒有退出前父進程是一直處于阻塞狀態的,這里子進程的作用同單線程中的函數類似。一旦子進程退出, WaitForSingleObject ()函數所等待的 pi.hProcess 對象將得到通知,父進程將得以繼續,如有必要可以通過 GetExitCodeProcess ()來獲取子進程的退出代碼。

  相比而言,更多的情況是父進程在啟動完子進程后就再不與其進行任何數據交換和通訊,由其創建的子進程的執行成功與否均與父進程無關。許多大型軟件在設計時也多采用了這類思想,將某些功能完全通過獨立的應用程序來完成,當需要執行某操作時只要通過主程序啟動相應的子進程即可,具體的處理工作均由子進程去完成。這類子進程的創建過程更為簡單,例如對于上面那段代碼只需去除對子進程句柄 pi.hProcess 的等待即可:

BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

if (ret) {

  // 關閉子進程的主線程句柄

  CloseHandle(pi.hThread);

  // 關閉子進程句柄

  CloseHandle(pi.hProcess);

}

  可以通過 dwCreationFlags 參數在創建進程時設置子進程的優先級。前面的示例代碼在創建子進程時使用的均是默認的優先級,如果要將優先級設置為高,可以修改如下:

BOOL ret = CreateProcess(NULL, cCommandLine, NULL, NULL, FALSE, HIGH_PRIORITY_CLASS, NULL, NULL, &si, &pi);

  如果在進程創建時沒有特別設置優先級,可以通過 SetPriorityClass ()函數來動態設定,該函數需要待操作進程的句柄和優先級標識符作為入口參數,函數原型為:

BOOL SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass);

  對于前面沒有設定優先級的例子代碼,可以在子進程啟動后由父進程來動態改變其優先級設置:

SetPriorityClass(pi.hProcess, HIGH_PRIORITY_CLASS);

  或是由子進程在其啟動后自行改變優先級設置,需要注意的是這時進程句柄應設置為子進程自身的句柄,可通過 GetCurrentProcess ()函數來獲取:

HANDLE hProcess = GetCurrentProcess();

SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);

  進程的互斥運行

  正常情況下,一個進程的運行一般是不會影響到其他正在運行的進程的。但是對于某些有特殊要求的如以獨占方式使用串行口等硬件設備的程序就要求在其進程運行期間不允許其他試圖使用此端口設備的程序運行的,而且此類程序通常也不允許運行同一個程序的多個實例。這就引出了進程互斥的問題。

  實現進程互斥的核心思想比較簡單:進程在啟動時首先檢查當前系統是否已經存在有此進程的實例,如果沒有,進程將成功創建并設置標識實例已經存在的標記。此后再創建進程時將會通過該標記而知曉其實例已經存在,從而保證進程在系統中只能存在一個實例。具體可以采取內存映射文件、有名事件量、有名互斥量以及全局共享變量等多種方法來實現。下面就分別對其中具有代表性的有名互斥量和全局共享變量這兩種方法進行介紹:

// 創建互斥量

HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");

// 檢查錯誤代碼

if (GetLastError() == ERROR_ALREADY_EXISTS) {

  // 如果已有互斥量存在則釋放句柄并復位互斥量

  CloseHandle(m_hMutex);

  m_hMutex = NULL;

  // 程序退出

  return FALSE;

}

  上面這段代碼演示了有名互斥量在進程互斥中的用法。代碼的核心是 CreateMutex ()對有名互斥量的創建。 CreateMutex ()函數可用來創建一個有名或無名的互斥量對象,其函數原型為:

HANDLE CreateMutex(

  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全屬性的指針

  BOOL bInitialOwner, // 初始化互斥對象的所有者

  LPCTSTR lpName // 指向互斥對象名的指針

);

  如果函數成功執行,將返回一個互斥量對象的句柄。如果在 CreateMutex ()執行前已經存在有相同名字的互斥量,函數將返回這個已經存在互斥量的句柄,并且可以通過 GetLastError ()得到錯誤代碼 ERROR_ALREADY_EXIST 。可見,通過對錯誤代碼 ERROR_ALREADY_EXIST 的檢測可以實現 CreateMutex ()對進程的互斥。

  使用全局共享變量的方法則主要是在 MFC 框架程序中通過編譯器來實現的。通過 #pragma data_seg 預編譯指令創建一個新節,在此節中可用 volatile 關鍵字定義一個變量,而且必須對其進行初始化。 Volatile 關鍵字指定了變量可以為外部進程訪問。最后,為了使該變量能夠在進程互斥過程中發揮作用,還要將其設置為共享變量,同時允許具有讀、寫訪問權限。這可以通過 #pragma comment 預編譯指令來通知編譯器。下面給出使用了全局變量的進程互斥代碼清單:

#pragma data_seg("Shared")

int volatile g_lAppInstance =0;

#pragma data_seg()

#pragma comment(linker,"/section:Shared,RWS")

……

if(++g_lAppInstance>1)

return FALSE;

  此段代碼的作用是在進程啟動時對全局共享變量 g_nAppInstancd 1 ,如果發現其值大于 1 ,那么就返回 FALSE 以通知進程結束。這里需要特別指出的是,為了使以上兩段代碼能夠真正起到對進程互斥的作用,必須將其放置在應用程序的入口代碼處,即應用程序類的初始化實例函數 InitInstance ()的開始處。

  結束進程

  進程只是提供了一段地址空間和內核對象,其運行是通過在其地址空間內的主線程來體現的。當主線程的進入點函數返回時,進程也就隨之結束。這種進程的終止方式是進程的正常退出,進程中的所有線程資源都能夠得到正確的清除。除了這種進程的正常推出方式外,有時還需要在程序中通過代碼來強制結束本進程或其他進程的運行。 ExitProcess ()函數即可在進程中的某個線程中使用,并將立即終止本進程的運行。 ExitProcess ()函數原型為:

VOID ExitProcess(UINT uExitCode);

  其參數 uExitCode 為進程設置了退出代碼。該函數具有強制性,在執行完畢后進程即已經被結束,因此位于其后的任何代碼將不能被執行。雖然 ExitProcess ()函數可以在結束進程的同時通知與其相關聯的動態鏈接庫,但是由于它的這種執行的強制性,使得 ExitProcess ()函數在使用上將存在有安全隱患。例如,如果在程序調用 ExitProcess ()函數之前曾用 new 操作符申請過一段內存,那么將會由于 ExitProcess ()函數的強制性而無法通過 delete 操作符將其釋放,從而造成內存泄漏。有鑒于 ExitProcess ()函數的強制性和不安全性,在使用時一定要引起注意。

   ExitProcess ()只能強制執行本進程的退出,如果要在一個進程中強制結束其他的進程就要用 TerminateProcess ()來實現。與 ExitProcess ()不同, TerminateProcess ()函數執行后,被終止的進程是不會得到任何關于程序退出的通知的。也就是說,被終止的進程是無法在結束運行前進行退出前的收尾工作的。所以,通常只有在其他任何方法都無法迫使進程退出時才會考慮使用 TerminateProcess ()去強制結束進程的。下面給出 TerminateProcess ()的函數原型:

BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);

 

  參數 hProcess uExitCode 分別為進程句柄和退出代碼。如果被結束的是本進程,可以通過 GetCurrentProcess ()獲取到句柄。 TerminateProcess ()是異步執行的,在調用返回后并不能確定被終止進程是否已經真的退出,如果調用 TerminateProcess ()的進程對此細節關心,可以通過 WaitForSingleObject ()來等待進程的真正結束。

  小結

  多進程是多任務管理中的重要內容,文中上述部分對其基本概念和主要的技術如子進程的創建與結束、進程間的互斥運行等做了較詳細的介紹。通過本文讀者應能對多進程管理有一個初步的認識。

posted on 2006-05-31 17:44 思勤無邪 閱讀(593) 評論(0)  編輯 收藏 引用 所屬分類: C++其他與技術相關
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            最新成人在线| 欧美激情女人20p| 一本到12不卡视频在线dvd| 亚洲制服少妇| 亚洲精品国产日韩| 欧美在线高清视频| 欧美亚洲日本网站| 欧美日韩免费看| 蜜桃伊人久久| 国产视频一区在线观看| 亚洲毛片av| 亚洲精品在线免费| 免费亚洲视频| 欧美在线你懂的| 欧美午夜一区二区| 亚洲精品在线观| 99在线观看免费视频精品观看| 亚洲无玛一区| 亚洲男人的天堂在线aⅴ视频| 欧美91福利在线观看| 免费看黄裸体一级大秀欧美| 欧美午夜a级限制福利片| 欧美成人精品1314www| 国产一区二区在线观看免费播放 | 亚洲影院色无极综合| 久久免费国产| 久久人人看视频| 黄色成人av网| 欧美在线视频全部完| 欧美专区在线播放| 国产欧美一区二区白浆黑人| 亚洲裸体视频| 一区二区三区蜜桃网| 欧美另类视频在线| 一区二区三区久久| 欧美在线观看你懂的| 国产日韩在线一区| 欧美一区二区三区在线观看| 久久国产精彩视频| 精品成人在线观看| 免费日韩一区二区| 亚洲欧洲日夜超级视频| 日韩性生活视频| 欧美日韩中文在线观看| 亚洲资源av| 麻豆精品视频在线观看视频| 亚洲激情在线播放| 欧美三区美女| 欧美一区二区播放| 亚洲国产成人久久| 亚洲欧美日韩一区二区三区在线观看 | 久热精品视频在线免费观看| 亚洲韩国青草视频| 亚洲欧美一区二区三区在线| 国产欧美日韩伦理| 麻豆精品一区二区综合av| 91久久国产综合久久91精品网站| 亚洲免费网址| 欲香欲色天天天综合和网| 欧美精品在线观看91| 先锋影音久久久| 亚洲国产精品久久精品怡红院| 亚洲视频播放| 伊人蜜桃色噜噜激情综合| 欧美日本精品在线| 久久人91精品久久久久久不卡 | 一本色道久久综合精品竹菊| 久久久www成人免费精品| 亚洲三级国产| 国产日韩欧美精品在线| 欧美人在线视频| 久久久久久九九九九| 99亚洲精品| 亚洲二区三区四区| 久久成人资源| 亚洲少妇自拍| 亚洲精品久久久久久久久久久久久 | 国产日韩精品久久| 欧美日韩免费高清一区色橹橹| 久久精品国产视频| 亚洲网友自拍| 亚洲乱码国产乱码精品精98午夜| 久久久久亚洲综合| 亚洲女人天堂成人av在线| 亚洲区欧美区| 在线电影一区| 国产一区二区高清| 国产精品老牛| 国产精品99免费看 | 日韩写真在线| 最新成人在线| 亚洲国产精品va在线看黑人| 国产日韩欧美日韩| 国产精品国产三级国产普通话三级| 欧美成人在线影院| 久久躁日日躁aaaaxxxx| 久久久久九九视频| 欧美在线观看视频一区二区| 亚洲伊人一本大道中文字幕| 亚洲伦理自拍| 日韩亚洲综合在线| 亚洲美女毛片| 亚洲毛片在线看| 亚洲精品在线免费观看视频| 亚洲国产欧美日韩| 亚洲激情午夜| 91久久久在线| 亚洲精品中文字幕在线| 亚洲人成高清| av不卡在线观看| 一本大道久久a久久精品综合| 亚洲三级视频在线观看| 亚洲精品乱码久久久久久| 亚洲精品久久| 一区二区日韩| 亚洲欧美日韩成人高清在线一区| 亚洲先锋成人| 午夜一区二区三区在线观看| 午夜视频在线观看一区二区| 性欧美1819性猛交| 久久九九全国免费精品观看| 久久精品一区中文字幕| 玖玖玖免费嫩草在线影院一区| 欧美 日韩 国产一区二区在线视频| 猛男gaygay欧美视频| 欧美精品色一区二区三区| 欧美日韩亚洲天堂| 国产女同一区二区| 在线观看国产精品淫| 亚洲精品久久久久久一区二区 | 亚洲一二三级电影| 欧美一区二区精品久久911| 久久精品成人| 欧美激情bt| 国产精品系列在线| 亚洲电影在线看| 妖精成人www高清在线观看| 亚洲欧美日韩一区二区三区在线| 久久精品日产第一区二区三区| 久久亚洲精品网站| 亚洲日韩中文字幕在线播放| 亚洲自拍偷拍色片视频| 久久在线播放| 国产精品久久婷婷六月丁香| 极品尤物一区二区三区| 亚洲视频日本| 免费av成人在线| 亚洲桃花岛网站| 美女精品国产| 国产日韩欧美亚洲| 亚洲精品五月天| 久久国产一区二区三区| 欧美激情五月| 亚洲欧美在线观看| 欧美精品久久久久久久| 国产日韩亚洲欧美综合| 亚洲精品你懂的| 久久爱www久久做| 亚洲精品看片| 久久综合中文字幕| 国产精品自拍三区| 日韩一本二本av| 牛牛国产精品| 欧美一区二区三区在线免费观看| 欧美精品一区二区三区四区| 激情综合五月天| 欧美在线视频一区二区三区| 亚洲精品永久免费精品| 久久综合久久综合久久| 国产欧美一区二区精品婷婷| 制服丝袜激情欧洲亚洲| 欧美激情一区二区三区蜜桃视频| 亚洲欧洲av一区二区| 欧美少妇一区二区| 日韩午夜电影| 欧美国产乱视频| 久久久久www| 国产日韩欧美综合| 亚洲免费在线| 一本色道久久| 欧美日韩三级电影在线| 亚洲精品女人| 欧美国产在线电影| 久久综合久久综合久久综合| 国产精品在线看| 午夜视频在线观看一区二区| 亚洲精品久久久一区二区三区| 鲁大师影院一区二区三区| 狠狠入ady亚洲精品经典电影| 欧美一区二粉嫩精品国产一线天| 在线性视频日韩欧美| 欧美三级电影网| 亚洲综合精品自拍| 亚洲少妇在线| 国产美女精品| 欧美一区网站| 久久精品一区二区国产| 在线观看亚洲精品| 欧美国产日韩一区二区| 欧美v日韩v国产v|