代码之家  ›  专栏  ›  技术社区  ›  Brian T Hannan

Windows线程:何时应使用InterlockedExchangeAdd()?

  •  0
  • Brian T Hannan  · 技术社区  · 15 年前

    准备工作 临界截面; int*p=malloc(sizeof(int));//分配地点 初始化关键部分(&cs);//首次写入提示

    螺纹#1 {

    螺纹#2 { *p=2;//第二次写入 }

    Run()
    {
    // some code
    m_bIsTerminated = TRUE;
    // some more code
    }
    

    然后,我在另一个线程中读取(可能同时):

    Terminate()
    {
    // some code
    if( m_bIsTerminated )
    {
    m_dwThreadId = 0;
    m_hThread = NULL;
    m_evExit.SetEvent();
    return;
    }
    // even more code
    }
    

    解决这种竞争状况的最佳解决方案是什么?关键部分是要走的路还是InterlockedExchangeAdd()的使用更有用?

    3 回复  |  直到 15 年前
        1
  •  0
  •   villintehaspam    15 年前

    InterlockedExchangeAdd用于将值作为原子操作添加到整数,这意味着您不必使用临界段。如果某个线程抛出异常,这也消除了死锁的风险——您需要确保不保留任何类型的锁,因为这会阻止其他线程获取该锁。

    对于您的场景,您肯定可以使用联锁…-函数,但我会使用事件(CreateEvent、SetEvent、WaitForSingleObject),可能是因为我经常发现自己需要等待多个对象(在您的场景中,您可以等待零秒)。

    Upd:对变量使用volatile可能有效,但不建议使用volatile,请参阅: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html http://www-949.ibm.com/software/rational/cafe/blogs/ccpp-parallel-multicore/tags/c%2B%2B0x

    如果你想随身携带,看看 boost::thread .

        2
  •  3
  •   Seva Alekseyev    15 年前

    InterlocatedXXX系列函数使用Intel CPU的原子3操作数命令(XADD和CMPXCNG)。因此,它们比关键部分便宜得多。线程安全分配所需的是InterlockedCompareeExchange()。

    UPD:将变量标记为volatile。

        3
  •  0
  •   BenMorel Pankaj Kumar    10 年前

    您的“竞争条件”是//more代码的各个元素可以以不同的顺序执行。您的变量对此没有帮助。您的目标是让它们以确定的顺序执行吗?如果是,则需要一个条件变量在一个线程上等待,并在另一个线程中设置。如果您只是不希望它们同时执行,则可以使用关键部分。