线程同步与互斥
- 介绍
多线程共存于应用程序中是现代操作系统的基本特性和重要标志,在程序的应用过程中,广泛用到线程的操作. - 好处
1>多线程中可以把程序细分成几个相对独立的模块,防止其中一个功能模块阻塞导致程序假死
2>可以提高运行的效率,使得程序模块化更强,有利于追踪程序执行过程和排查问题. - 介绍
多线程同时访问共享对象时需要引入同步和互斥的机制.
同步:是指多个任务按照约定的顺序相互配,由信号量决定线程是否继续运行还是阻塞等待.
互斥:线程间的互斥,目的是用来保证共享资源数据操作的完整性。
每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源。线程必须先获得互斥锁才能访问临界资源,访问完临界资源后释放该锁。如果无法获得锁,线程会阻塞知道获得锁为止。 实例
同步:
“`
HANDLE m_Event;
list m_list;
int Receive()
{AfxBeginThread(Thread,NULL);
m_Event= CreateEvent( NULL, TRUE, FALSE, NULL );
m_list.push_back(m);
if(m_list.size() == 1)
{
SetEvent(m_Event);
}
}
UINT Thread(LPVOID lParam)
{
while(m_list > 0)
{}
ResetEevnt(m_Event);
WaitForSingleObject(m_Event,INFINITE);
return 0;
}
同步过程,开始创建进程AfxBeginThread,创建事件CreateEvent.
当list链表插入数据时,SetEvent设置事件有信号,在线程中进行处理,当链表没有数据时,跳出while循环,ResetEvent设置事件没有信号,并调用WaitForSingleObject进行等待(INFINITE为无限期等待),直到再次的讲事件设为有信号,线程一直处于等待状态.
互斥:
CRITICAL_SECTION cs;
static int n_AddValue = 0;
//第一个线程
UINT FirstThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁 接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
n_AddValue ++;
}
LeaveCriticalSection(&cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作
return 0;
}
//第二个线程
UINT SecondThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁
n_AddValue ++;
LeaveCriticalSection(&cs);//解锁
return 0;
}
互斥过程中,两个线程分别对变量n_AddValue进行操作.当其中一个进行操作时,加锁,另一个线程处于等待状态.当操作完成,解锁后,才能进行变量的操作.