一些概念
进程和线程的概念: 套用 孙鑫的来说 进程就好像一个手术室.线程就是里面的医生,线程当中一定有一个主线程也就是程序里的main或winmain.记住代码不是线程.代码相当于医生的手术方案,你完成了手术方案,你医生就完成工作了. 也就是说代码的结束相当于线程的结束.一个进程当中可以有1个以上的线程.当然在程序当中你必须自己创建新的线程咯.
我们可以当创建一个新线程为主刀医生叫一个新的助手
创建线程:CreateThread()第一个参数表明安全性 指向SECURITY_DESCRIPTOR 我们设为NULL,默认安全性 ,//因为助手做的事不大,所以对他的安全放低
第二个参数创建线程的栈的大小 以字节为单位.我们可以设为0 表明创建与调用此函数的线程默认大小的栈 //就当提供给助手和叫他来的人一样多的器具吧
第三个参数函数地址 表明线程进入的函数地址的入口点 ,//就是告诉助手 他要实行的方案 在某个地方
第四个参数设为CREATE_SUSPENDED表明创建后不运行,直到ResumeThread调用才执行,设为0表明创建后就让他执行.
第五个参数表明ID //对ID不感兴趣 不接收 设为NULL
时间片:每个线程都有一段执行的时期. 形象点说,如果手术不大,要不了多少时间的话,可能主刀医生一个人做完了但他不能预料进展还是叫了两个助手,其余两个助手没时间上场,因为整个手术时间短了刚好是主刀医生所做的.当然可能手术较大,主刀医生迅速做完了前面的没他事了,剩余其他的大量重复性工作,他可以留给助手做,在他休息睡觉这段时期,两个助手可以轮流做他们的事,例如1号助手做两分钟,2号做两分钟,然后又1号,就这样循环,直到主刀医生睡醒后,叫他们够了然后整个就结束了.
互斥对象:内核对象还包含了线程ID和使用计数 可以把它当成一把智能的钥匙.
创建互斥对象:
HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOLbInitialOwner, LPCTSTRlpName );
第一个参数 表明安全性NULL 第二个参数表明调用他的线程是要要获得互斥对象的权限true则为是 最后一个表明创建互斥对象的名字为NULL则为匿名
调用成功则返回 互斥对象句柄.
如果在创建的一个命名的互斥对象之前已经有了这个命名对象,则会返回之前的互斥对象句柄.可以根据GetLastError()==ERROR_ALREADY_EXISTS判断之前是否已经有了一个同名的互斥对象存在了,所以根据这个可以让程序只运行一个实例,就像一些游戏一样.
获得互斥对象的权限
除了在创建的时候指定获得权限外,还可以调用DWORD WaitForSingleObject( HANDLE hHandle, DWORDdwMilliseconds );此函数获得互斥对象的所有权,第一个参数要获得的互斥对象的句柄,第二个等待的时间以毫秒为单位 指定为INFINITE将一直等待.
互斥对象将其当做一把智能钥匙,如果这把智能钥匙已经在别人手里掌握了拥有权限的话,那么它将是无信号的.
除非调用此函数的线程ID==拥有此互斥对象的ID 不过如果已经拥有了的话 你再去调用此函数 会将计数器+1
释放互斥对象.
规则:谁有这把钥匙,就由谁来释放它的权限.
还有一种情况就是 线程结束了,自动释放它的拥有权限.
BOOL ReleaseMutex( HANDLE hMutex); //这个参数就不解释了
实例代码:
#include <windows.h>
#include <iostream.h>
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;
}