多线程的同步和异步
异步: 例如赛跑,各跑各的。
同步: 例如接力赛,必须接班后才能跑(一个线程必须等到另一个线程的信号等)
互斥: 例如独木桥,一次只能过一个(线程)
在WIN32中同步机制主要有以下几种:
(1)临界区(Critical Section)
(2)信号量(Senaphore)
(3)互斥量(Mutex)
(4)事件(Event)
用户模式下的方法有:
1.原子操作,临界区。
2.通过对多线程的串行化来访问公共资源或一段代码,速度快,色和控制数据访问。
内核模式下的方法有:
1.互斥量:为协调共同对一个共享资源的单独访问而设计。
2.信号量:为控制一个具有有限数量用户资源而设计。
3.事件:用来统治线程有一些事件已发生,从而启动后继任务的开始。
临界区结构对象
CRITICAL_SECTION Section;
备注:(人工无法干预)
1.临界区在使用时以CRITICAL_SECTION结构对象保护共享资源。
2.如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。
3.临界区在被释放后,其他线程可以继续抢占,并一次达到用原子方式操作共享资源的目的。
初始化临界区
InitializeCriticalSection(&Section);
进入临界区(线程内)
EnterCriticalSection(&Section);
离开临界区(线程内)
LeaveCriticalSection(&Section);
尝试进入临界区(线程内)
TryEnterCriticalSection(&Section); 多用于if语句内
返回:
成功:TRUE
失败 : FALSE
备注:(EnterCriticalSection 和 TryEnterCriticalSection)
EnterCriticalSection:
1.如果EnterCriticalSection的代码已经被占用,会使调用线程置于阻塞状态。
2.处于阻塞状态,那么该线程可能很长时间内不能被调度。
TryEnterCriticalSection:
1.TryEnterCriticalSection函数决不允许调用线程进入等待状态。
2.它的返回值能够指明调用线程是否能够获得对资源的访问权。
3.TryEnterCriticalSection 发现该资源已经被另个线程访问,它返回FALSE,否则TRUE。
4.运用这个函数,线程能够迅速查看它是否可以访问某个共享资源,如果不能访问,那么它可以继续执行某些其他操作,而不必进行等待。
删除临界区
DeleteCriticalSection(&Section);
#include<process.h>
#include<windows.h>
#include<iostream>
using namespace std;
int tickets = 100;
//1.创建临界区
CRITICAL_SECTION section;
void ThreadFun1(void*p);
void ThreadFun2(void*p);
int main()
{
//2.初始化临界区
InitializeCriticalSection(§ion);
cout << "开始!" << endl;
HANDLE hThread1 = (HANDLE)_beginthread(ThreadFun1, 0, "窗口A");
HANDLE hThread2 = (HANDLE)_beginthread(ThreadFun2, 0, "窗口B");
HANDLE hArry[] = { hThread1,hThread2 };
WaitForMultipleObjects(2, hArry, true, INFINITE);
cout << "结束!" << endl;
//5.删除临界区
DeleteCriticalSection(§ion);
system("pause");
return 0;
}
void ThreadFun1(void * p)
{
char * name = (char*)p;
cout << name << "开始售票" << endl;
while (tickets > 0)
{
//3.进入临界区
//EnterCriticalSection(§ion);
//3.尝试进入,与上一样 只是不会阻塞
if (TryEnterCriticalSection(§ion))
{
if (tickets > 0)
printf("%s窗口卖出第%d张票!\n", name, tickets--);
//4.离开临界区
LeaveCriticalSection(§ion);
}
}
}
void ThreadFun2(void * p)
{
char * name = (char*)p;
cout << name << "开始售票" << endl;
while (tickets > 0)
{
//3.进入临界区
EnterCriticalSection(§ion);
if (tickets > 0)
printf("%s窗口卖出第%d张票!\n", name, tickets--);
//4.离开临界区
LeaveCriticalSection(§ion);
}
}
内容均为学习笔记