如果函数不在线程内返回,如何保证函数不会再次输入?

时间:2009-03-25 08:58:12

标签: c++ winapi synchronization synchronous

我不希望多个线程同时输入该功能,也不希望在尚未返回时再次输入该功能。有没有办法实现我的目标?非常感谢你!

7 个答案:

答案 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等)。但我希望它能给你一些有用的想法。