互斥体实现了互相排斥(mutual exclusion)同步的简单形式。互斥体禁止多个线程同时进入受保护的代码临界区(critical section)。因此,在任意时刻,只有一个线程被允许进入这样代码保护区。
任何线程在进入临界区之前,必须获取acquire与此区域相关的互斥体的所有权。如果已有另一线程拥有了临界区互斥体,其他线程就不能再进入其中。这些线程必须等待,知道当前的属主线程释放release该互斥体。
什么时候需要使用互斥体呢?互斥体用于保护共享的易变代码,也就是,全局或静态数据。这样的数据必须通过互斥体进行保护,以防止它们在多个线程同时访问时损坏。
如下示例:
#include <QtCore/QCoreApplication>
#include "ace/Synch.h"
#include "ace/Log_Msg.h" //ace_debug
#include "ace/OS_NS_stdio.h" ///ACE_OS::printf
#include "ace/Thread.h"
struct Args
{
public:
Args(int iterations):mutex_(),iterations_(iterations) {}
ACE_Thread_Mutex mutex_;
int iterations_;
};
///the starting point for the worker threads
static void* worker(void *arguments)
{
Args *arg= (Args*) arguments;
for(int i=0; i<arg->iterations_; i++)
{
ACE_DEBUG((LM_DEBUG,"(%t) Trying to get a hold of this iteration\n"));
///this is our critical section
arg->mutex_.acquire(); ///acquire: 获得
ACE_DEBUG((LM_DEBUG,"(%t) This is iteration number %d\n",i));
ACE_OS::sleep(2);
//simulate critical(关键,临界) work
arg->mutex_.release();
}
return 0;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if(argc<2)
{
ACE_OS::printf("Usage: %s <number_of_threads> <num_of_iterations>\n",argv[0]);
ACE_OS::exit(1);
}
Args arg(ACE_OS::atoi(argv[2]));
//setup the arguments
int n_threads= ACE_OS::atoi(argv[1]);
ACE_thread_t *threadID=new ACE_thread_t[n_threads+1]; ///DWORD
ACE_hthread_t *threadHandles=new ACE_hthread_t[n_threads+1]; ///HANDLE
if(ACE_Thread::spawn_n(threadID, id's for each of the threads
n_threads, number of threads to spawn
(ACE_THR_FUNC)worker, ///entry point for new thread
&arg, args to worker
THR_JOINABLE | THR_NEW_LWP, //flags
ACE_DEFAULT_THREAD_PRIORITY,
0,0,threadHandles)==-1)
{
ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n"));
}
for(int i=0; i<n_threads; i++)
ACE_Thread::join(threadHandles[i]);
return 0;///a.exec();
}
(9912) Trying to get a hold of this iteration
(9912) This is iteration number 0
(7312) Trying to get a hold of this iteration
(7312) This is iteration number 0
(9912) Trying to get a hold of this iteration
(9912) This is iteration number 1
(7312) Trying to get a hold of this iteration
(9912) Trying to get a hold of this iteration
(7312) This is iteration number 1
(7312) Trying to get a hold of this iteration
(9912) This is iteration number 2
(9912) Trying to get a hold of this iteration
(7312) This is iteration number 2
(7312) Trying to get a hold of this iteration
(7312) This is iteration number 3
(9912) This is iteration number 3
请按任意键继续. . .