1

我不希望该函数被多个线程同时输入,我也不希望它尚未返回时再次输入。有什么方法可以实现我的目标吗?非常感谢!

4

7 回答 7

8

这两个目标都可以通过互斥信号量来实现。

于 2009-03-25T09:04:10.313 回答
3

正如其他答案所解释的那样,在一个线程上进行时阻止其他线程进入该函数非常简单。但是如果你想让它在它已经被输入时阻塞在同一个线程中......好吧,那是一个死锁。

于 2009-03-25T09:11:35.273 回答
3

使用临界区(InitializeCriticalSection()、EnterCriticalSection()、LeaveCriticalSection())并实现一个入口计数器。临界区将防止来自不同线程的重新进入,而入口计数器将防止来自同一线程的重新进入。

要实现条目计数器,请使用公共变量(您的情况为布尔值)和括号类。一旦你已经进入临界区(因此没有其他线程将并行执行相同的代码)检查变量的值。如果它声明该函数已被输入 - 离开(首先释放关键部分,然后离开该函数)。否则,构造将更改变量值的括号类实例。所以下次这个线程进入函数时,它会检查变量,看到重新进入已经发生并离开。离开函数后,括号类的析构函数会将变量更改为其原始值。

对临界区条目和条目计数器更改使用括号类是明智的,这样您的代码是异常安全的,并且所有操作都按必要的顺序执行,无论您如何离开函数 - 在异常或返回语句时。

于 2009-03-25T09:46:57.543 回答
1

f will only be called runs only, when nobody else is currently running it. (This is concept demonstration with only Win32 calls)

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;
}

Beware the minimal checking, the missing cleanup code for the mutex and the race-condition on first enter.

于 2009-03-25T14:01:20.600 回答
1

既然您说的是 C++ 和 Windows,请查看关键部分。不过,为了便于使用,您可能希望将其包装在几个 C++ 类中。

如果锁已经被占用,关键部分会尝试短时间的自旋循环。对于较短的代码,这通常可以避免完全阻塞等待,从而避免用户<>内核模式等的开销。

于 2009-03-25T09:25:30.233 回答
0

通常您需要引入一个监视器,例如在Java 中通过将“同步”关键字添加到您的方法签名中。

(我对吗?)

于 2009-03-25T09:05:35.490 回答
0

你可以这样做:

int some_shared_var = 0;
...
for (;some_shared_var != rank;) ;
run_my_function();
some_shared_var++;

rank 是您的线程号(假设您有编号为 0 到 size-1 的线程)。

这只是一个例子。真正的实现会有所不同。这取决于您要使用哪些库/函数来并行化代码(fork、MPI 等)。但我希望它能给你一些有用的想法。

于 2009-03-25T09:22:42.190 回答