【问题标题】:Failure in synchronization APIs for C++ code under WindowsWindows 下 C++ 代码同步 API 失败
【发布时间】:2012-09-08 23:09:15
【问题描述】:

如果我像这样定义模板结构:

template <typename T> 
struct SYNCHED_DATA
{
    SYNCHED_DATA()
    {
        hMutex = ::CreateMutex(NULL, FALSE, NULL);
    }
    ~SYNCHED_DATA()
    {
        if(hMutex)
            CloseHandle(hMutex);
        hMutex = NULL;
    }

    void set(T* pV)
    {
        if(pV)
        {
            ::WaitForSingleObject(hMutex, INFINITE);
            var = *pV;
            ::ReleaseMutex(hMutex);
        }
    }
    void get(T* pV)
    {
        if(pV)
        {
            ::WaitForSingleObject(hMutex, INFINITE);
            *pV = var;
            ::ReleaseMutex(hMutex);
        }
    }

private:
    HANDLE hMutex;
    T var;

    SYNCHED_DATA(const SYNCHED_DATA& s)
    {
    }
    SYNCHED_DATA& operator = (const SYNCHED_DATA& s)
    {
    }
};

我可以确定那些 WaitForSingleObject() API 将始终返回 WAIT_OBJECT_0 吗?如果不是,在什么情况下会失败,我应该如何处理?

【问题讨论】:

  • The documentation 详细介绍了返回码。
  • "WAIT_FAILED = 函数失败。要获取扩展错误信息,请调用 GetLastError。" ——你可以“详细”吗???
  • 我的意思是它具有所有可能的返回值及其含义。如果您没有注意到,GetLastError() 使用的错误列表也是巨大的。
  • 那又如何,我需要一个“巨大”的 switch 语句来处理它们?
  • 如果您发现自己遇到了其中一个问题,通常最好显示/记录错误代码,并可选择使用FormatMessage 将其转换为描述错误的字符串。

标签: c++ winapi synchronization


【解决方案1】:

The Old New Thing 有一篇关于如何在等待成功之前关闭句柄将导致任何等待的人 WAIT_ABANDONED 的文章:

http://blogs.msdn.com/b/oldnewthing/archive/2005/09/12/463977.aspx

在这个网站上有一些关于WAIT_FAILED 的讨论:

Why would WaitForSingleObject return WAIT_FAILED

这些表明即使无限超时也有可能失败。

【讨论】:

  • 对不起,在我上面发布的代码中等待成功之前,如何关闭句柄?也许我只是什么都没看到......
  • 一个线程运行get,例如,获取互斥体,然后开始复制。 (假设你有SYNCHED_DATA&lt;std::vector&lt;std::string&gt; &gt;,或者其他东西,里面有很多字符串。)1+ 其他线程同时尝试获取互斥锁,并最终等待。然后另一个线程在此过程中销毁 SYNCHED_DATA 对象。这有点做作,但我认为没有提供足够的信息来证明这不可能发生。
  • 好的,一种可能是线程在拥有互斥锁时被终止。但我什至没有在我的代码中使用 TerminateThread API。
  • 你必须弄清楚这些信息是否与你的代码整体相关;我认为这肯定与问题中提供的 sn-p 有关,没有上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 2011-01-22
  • 1970-01-01
相关资源
最近更新 更多