简单的线程同步

时间:2009-03-11 16:21:18

标签: c++ winapi mfc

我需要一个简单的“一次一个”锁定一段代码。考虑可以从多个线程运行的函数func

void func()
{
     // locking/mutex statement goes here
     operation1();
     operation2();
     // corresponding unlock goes here
     operation3();
}

我需要确保operation1operation2始终“一起”运行。使用C#,我会在这两个调用周围使用一个简单的lock块。什么是C ++ / Win32 / MFC等价物?

大概是某种Mutex

5 个答案:

答案 0 :(得分:27)

修正上述Michael solution

迈克尔解决方案非常适合C应用程序。但是当在C ++中使用时,由于异常的可能性,不鼓励这种风格。如果在operation1或operation2中发生异常,则临界区将无法正确保留,所有其他线程将阻止等待。

// Perfect solutiuon for C applications
void func()
{
    // cs previously initialized via InitializeCriticalSection
    EnterCriticalSection(&cs);
    operation1();
    operation2();
    LeaveCriticalSection(&cs);
    operation3();}
}

// A better solution for C++
class Locker
{
    public:
    Locker(CSType& cs): m_cs(cs)
    {
        EnterCriticalSection(&m_cs);
    }
    ~Locker()
    {
        LeaveCriticalSection(&m_cs);
    }
    private:
        CSType&  m_cs;
}
void func()
{
    // cs previously initialized via InitializeCriticalSection
    {
        Locker  lock(cs);
        operation1();
        operation2();
    }
    operation3();
}

答案 1 :(得分:19)

关键部分将起作用(它们的重量轻于互斥体。)InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection和DeleteCriticalSection是要在MSDN上查找的函数。

void func()
{
    // cs previously initialized via InitializeCriticalSection
    EnterCriticalSection(&cs);
    operation1();
    operation2();
    LeaveCriticalSection(&cs);
    operation3();}
}

编辑: 关键部分比互斥体更快,因为关键部分主要是用户模式基元 - 在无竞争获取的情况下(通常是常见情况),没有系统调用内核,并且获取大约需要数十个周期。内核交换机更昂贵(大约数百个周期)。关键部分调用内核的唯一时间是为了阻塞,这涉及等待内核原语(互斥或事件)。获取互斥锁总是涉及对内核的调用,因此速度要慢几个数量级。 但是,关键部分只能用于在一个进程中同步资源。为了跨多个进程进行同步,需要一个互斥锁。

答案 2 :(得分:6)

最好的方法是使用临界区,使用EnterCriticalSection和LeaveCriticalSection。唯一令人讨厌的部分是你需要首先使用InitializeCriticalSection初始化一个关键部分。如果此代码在类中,则将初始化放在构造函数中,将CRITICAL_SECTION数据结构作为类的成员。如果代码不是类的一部分,则需要使用全局或类似的东西来确保它被初始化一次。

答案 3 :(得分:6)

  1. 使用MFC:

    1. 定义同步对象。 (Mutext或Critical部分)

      1.1如果属于不同进程的多个线程进入 func()然后使用CMutex。

      1.2。如果同一进程的多个线程进入func(),则使用 CCriticalSection。

    2. CSingleLock可用于简化同步对象的使用。
  2. 让我们说我们已经定义了关键部分

     CCriticalSection m_CriticalSection;
        void func()
        {
             // locking/mutex statement goes here
             CSingleLock aLock(&m_CriticalSection, **TRUE**); 
           // TRUE indicates that Lock aquired during aLock creation.
           // if FALSE used then use aLock.Lock() for locking.
    
             operation1();
             operation2();
              // corresponding unlock goes here
              aLock.Unlock();
             operation3();
        }
    
      

    编辑:参考MSDN的VC ++文章:Multithreading with C++ and MFC Classes和   Multithreading: How to Use the Synchronization Classes

答案 4 :(得分:2)

你可以试试这个:

void func()
{
    // See answer by Sasha on how to create the mutex
    WaitForSingleObject (mutex, INFINITE);
    operation1();
    operation2();
    ReleaseMutex(mutex);
    operation3();
}