进程组成:
<1> 操作系统用来管理进程的内核对象
<2>地址空间
线程组成:
<1>线程的内核对象
<2>线程栈
线程创建函数:CreateThread
互斥对象属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID和一个计数器。其中ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。
为了创建互斥对象,需要调用函数CreateMutex,该函数可以创建或打开一个命名的或匿名的互斥对象,然后程序就可以利用互斥对象完成线程间的同步。
(1) 对互斥对象来说,谁拥有谁释放
(2)操作系统通过互斥对象内部的计数器来维护同一个线程请求到该互斥对象的次数,ReleaseMutex()函数释放该互斥对象时就是递减这个计数器
(3) 根据WaitForSingleObject函数的返回值可以知道当前线程是如何得到互斥对象的所有权的:(1)正常得到(2)先前拥有该对象的线程退出后获得的
#include <windows.h> #include <iostream> using namespace std; DWORD WINAPI Fun1Proc( LPVOID lpParameter // thread data ); DWORD WINAPI Fun2Proc( LPVOID lpParameter // thread data ); int index=0; int tickets=100; HANDLE hMutex; void main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); /*while(index++<1000) cout<<"main thread is running"<<endl;*/ hMutex=CreateMutex(NULL,TRUE,NULL); /*hMutex=CreateMutex(NULL,TRUE,"tickets"); if(hMutex) { if(ERROR_ALREADY_EXISTS==GetLastError()) { cout<<"only instance can run!"<<endl; return; } }*/ WaitForSingleObject(hMutex,INFINITE); ReleaseMutex(hMutex); ReleaseMutex(hMutex); Sleep(4000); // Sleep(10); } DWORD WINAPI Fun1Proc( LPVOID lpParameter // thread data ) { /*while(index++<1000) cout<<"thread1 is running"<<endl;*/ while(TRUE) { //ReleaseMutex(hMutex); WaitForSingleObject(hMutex,INFINITE); if(tickets>0) { Sleep(1); cout<<"thread1 sell ticket : "<<tickets--<<endl; } else break; ReleaseMutex(hMutex); } //WaitForSingleObject(hMutex,INFINITE); //cout<<"thread1 is running"<<endl; return 0; } DWORD WINAPI Fun2Proc( LPVOID lpParameter // thread data ) { while(TRUE) { //ReleaseMutex(hMutex); WaitForSingleObject(hMutex,INFINITE); if(tickets>0) { Sleep(1); cout<<"thread2 sell ticket : "<<tickets--<<endl; } else break; ReleaseMutex(hMutex); } //WaitForSingleObject(hMutex,INFINITE); //cout<<"thread2 is running"<<endl; return 0; }