程序是计算机指令的几何,以文件的形式存在磁盘上。进程被定义为正在运行的程序的实例,是在进行地址空间中的一次执行活动。一个程序可以对应多个进程,如可以通过打开多个Word程序,每个word的应用就是一个进程。同时一个进程可以访问多个程序。进程是系统资源申请、调度、运行的独立单位。程序不占用系统的运行资源。
进程由两部分组成:(1)操作系统用管理进程的内核对象,一个OS内部分配的一个内存块(数据结构),并且只对操作系统可见,进程只能通过"OS提供的API"来操作这个“内存对象”;(2)地址空间,包含进程所有可执行模块,或者DLL模块的代码和数据,以及可以用于进程动态分配的空间,如线程的栈空间Stacks,以及堆空间Heap。
进程是线程的容器,一个进程至少拥有一个主线程,被称为“主线程”,即maiin函数线程,即主线程进入点。主线程可以创建其他线程。进程是所有线程执行环境,是真正完成代码执行。这些线程“同时”执行进程地址空间中的代码。不同的进程之间不能相互访问。同一进程的不同线程之间可以相互访问。
线程由两部分组成:(1)线程的内核对象。 被OS创建,用于被OS管理线程的最小单位(2)线程栈Stack。用于维护执行线程过程中所需要的所有函数参数和局部变量。
当进程创建线程时,OS首先创建“线程内核对象”,OS从进程的地址空间分配内存供其“线程栈”使用。新线程可以访问进程的内核对象的所有“进程的内核对象的所有句柄”“进程中的所有内存”“本进程中的所有线程的堆栈”。所以单个进程间的所有线程之间可以非常容易相互通信。
由于创建线程的资源比较少,一般采用单进程多线程解决问题。即所谓的“多线程编程”艺术。不采用多进程解决问题的原因(1)创建进程的代价大,且进程之间的通信比较困难;(2)进程之间切换时代价也比较大,不同进程需要切换整个地址空间,但是线程切换的只是少量的执行环境。
多线程编程中,多线程采用时间片轮转的方式,在宏观上实现“同时”运行。如果计算机有多CPU或者多核,则可以真正实现多线程编程,且真正并行编程。
创建线程函数的WinOSAPI:CreateThread(),此函数创建一个线程,函数原型如下:
static HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD dwStackSize, LPTHREAD_START_ROUTINE pfnThreadProc, void* pvParam, DWORD dwCreationFlags, DWORD* pdwThreadId ) throw( );
DWORD WINAPI ABCThreadProcABC( _In_ LPVOID lpParameter );
HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, 如果为NULL,则使用默认的安全性
_In_ BOOL bInitialOwner, 即确定互斥对象的初始拥有者,否则此线程将不能后的所创建的互斥对象的所有权。True,则本线程初始拥有此互斥对象,如果本线程不释放,则其他线程不能等待拥有。
_In_opt_ LPCTSTR lpName 指定互斥对象的名称,如果为NULL,则是匿名互斥对象。
);
1 // ConsoleTest.cpp : 定义控制台应用程序的入口点。 2 // 3 #include "stdafx.h" 4 #include <iostream> 5 #include <Windows.h> 6 using namespace std; 7 int tick = 100; 8 HANDLE hMutex = NULL; 9 DWORD WINAPI funName1(LPVOID para) 10 { 11 while (true) 12 { 13 WaitForSingleObject(hMutex, INFINITE); 14 if (tick > 0) 15 cout << " threadAAAAAA sell 1 tick " << tick-- << endl; 16 else 17 break; 18 ReleaseMutex(hMutex); 19 } 20 return 0; 21 } 22 DWORD WINAPI funName2(LPVOID para) 23 { 24 while (true) 25 { 26 WaitForSingleObject(hMutex, INFINITE); 27 if (tick > 0) 28 cout << " threadBBBBB sell 1 tick " << tick-- << endl; 29 else 30 break; 31 ReleaseMutex(hMutex); 32 } 33 return 0; 34 } 35 36 int _tmain(int argc, _TCHAR* argv[]) 37 { 38 HANDLE handle1 = nullptr; 39 HANDLE handle2 = nullptr; 40 DWORD threadID1 = NULL; 41 DWORD threadID2 = NULL; 42 handle1 = CreateThread(NULL, 0, funName1, NULL, 0, &threadID1); 43 handle2 = CreateThread(NULL, 0, funName2, NULL, 0, &threadID2); 44 45 cout << "main Thread is running..." << handle1 << threadID1 << endl; 46 cout << "main Thread is running..." << handle2 << threadID2 << endl; 47 cout << "--------------------" << endl; 48 CloseHandle(handle1); 49 CloseHandle(handle2); 50 cout << "main Thread is running..." << handle1 << threadID1 << endl; 51 cout << "main Thread is running..." << handle2 << threadID2 << endl; 52 hMutex = CreateMutex(NULL, false, _T("AAAA")); 53 // 54 system("pause"); 55 return 0; 56 }
#ifdef __cplusplus #define NULL 0 #else /* __cplusplus */