我不希望多个线程同时输入该功能,也不希望在尚未返回时再次输入该功能。有没有办法实现我的目标?非常感谢你!
答案 0 :(得分:8)
这两个目标都可以使用互斥信号量来实现。
答案 1 :(得分:3)
如其他答案所解释的那样,在一个线程上正在进行的其他线程阻止该函数被输入是非常简单的。但是如果你想让它在已经被输入的同一个线程中阻塞......那么,这就是一个僵局。
答案 2 :(得分:3)
使用临界区(InitializeCriticalSection(),EnterCriticalSection(),LeaveCriticalSection())并实现一个条目计数器。关键部分将防止来自不同线程的重新进入,并且进入计数器将防止从同一线程重新进入。
要实现条目计数器,请使用公共变量(对于您的案例为布尔值)和括号类。一旦您已进入临界区(因此没有其他线程将并行执行相同的代码),请检查变量的值。如果它已声明已经输入了该功能 - 请离开(首先释放临界区,然后保留该功能)。否则,构造将更改变量值的括号类实例。所以下一次这个线程进入函数时它将检查变量,看到重新进入已经发生并离开。离开函数后,括号类的析构函数会将变量更改为其原始值。
对于临界区条目和条目计数器更改都使用括号类是明智的,这样您的代码就是异常安全的,并且所有操作都按照必要的顺序执行,无论您如何离开函数 - 异常或返回言。
答案 3 :(得分:1)
既然您正在说C ++和Windows,请查看critical sections。但是,为了便于使用,您可能希望将其包装在几个C ++类中。
如果已经采取锁定,关键部分会尝试短时间旋转。对于简短的代码片段,这通常可以避免执行完全阻塞等待,从而避免用户<>内核模式等的开销。
答案 4 :(得分:1)
f只会被称为仅运行,当没有其他人正在运行它时。 (这是仅使用Win32调用的概念演示)
void f();
err call_f()
{
static HMUTEX hMutex;
if( !hMutex )
{
hMutex = ::CreateMutex( 0, TRUE, 0 );
}
else
{
if( WaitForSingleObject( hMutex, 0 ) != WAIT_OBJECT_0 )
return ERR_ALREADY_RUNNING;
}
// calling f here
f();
ReleaseMutex( hMutex );
return S_OK;
}
首先输入最小的检查,互斥锁的缺失清理代码和竞争条件。
答案 5 :(得分:0)
通常你需要引入一个监视器,例如在Java中,通过在方法签名中添加“synchronized”关键字。
(我是对的吗?)
答案 6 :(得分:0)
您可以这样做:
int some_shared_var = 0;
...
for (;some_shared_var != rank;) ;
run_my_function();
some_shared_var++;
rank是你的线程编号(假设你的线程的编号为0到size-1)。
这只是一个例子。真正的实施将是不同的。这取决于您要用于并行化代码的库/函数(fork,MPI等)。但我希望它能给你一些有用的想法。