当前位置:  开发笔记 > 编程语言 > 正文

简单的线程同步

如何解决《简单的线程同步》经验,为你挑选了4个好方法。

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

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

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

想必是某种Mutex



1> Martin York..:

修复Michael解决方案.

Michael解决方案非常适合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();
}



2> Michael..:

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

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

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


Nils - 更新了为什么关键部分更快的答案.它们不仅仅是互斥体的包裹.
你应该把它包装在一个对象中.使用这样的C代码并非异常安全.

3> Murray..:

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



4> aJ...:

    使用MFC:

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

      1.1如果属于不同进程的多个线程进入func(),则使用CMutex.

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

      CSingleLock可用于简化同步对象的使用.

让我们说我们已经定义了临界区

 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++文章:使用C++和MFC类和 多线程进行多线程处理:如何使用同步类

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有