我是否需要为此代码添加同步?

时间:2012-03-21 12:44:56

标签: c windows

我正在编写一些代码来执行与DLL的显式链接。此代码作为隐式链接与.lib文件的替代方式提供给我的用户。目前,我计划的代码如下所示:

void DisableModule(int Module)
{
    typedef void (*DisableModuleProc)(int);
    static DisableModuleProc proc = NULL;
    if (proc == NULL)
        proc = (DisableModuleProc)GetProcAddress(hModule, "DisableModule");
    proc(Module);
}

这个表单有很多功能,为了解决这个问题,我已经删除了错误检查。

我的问题涉及线程安全。可以从多个线程同时调用此函数。显然,静态变量_DisableModule上存在竞争。我的信念是因为_DisableModule将在机器字边界(32或64位边界,取决于目标)上对齐,所以不会发生撕裂,因此种族是良性的。 GetProcAddress可能被调用的次数超过必要的次数,但我认为这不会影响程序的正确性。

我的分析是否正确?

2 个答案:

答案 0 :(得分:1)

此代码在x86和amd64上完全安全。 在最坏的情况下,GetProcAddress被多次调用。

在其他架构上,可能存在部分写入被中断的问题。为了避免这种情况,你可以使用原子(InterlockedComparExchange ...),但这在这里是多余的。

答案 1 :(得分:0)

一个简单的锁应该这样做 你应该只在proc==NULL时使用锁,所以一段时间后它就永远不会被拿走。所以争论不是问题 您可以在持有锁定的情况下致电GetProcAddress,或不使用锁定。{/ p>

选项1:

if (proc == NULL) {
    lock();
    proc = (DisableModuleProc)GetProcAddress(hModule, "DisableModule");
    unlock();
}

选项2:

if (proc == NULL) {
    DisableModuleProc tmp = (DisableModuleProc)GetProcAddress(hModule, "DisableModule");
    lock();
    if (proc == NULL) {
        proc = tmp;
    } else {
        // Any free needed?
    }
    unlock();
}