首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >简单线程同步

简单线程同步
EN

Stack Overflow用户
提问于 2009-03-11 16:21:18
回答 5查看 19.7K关注 0票数 8

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

代码语言:javascript
运行
复制
void func()
{
     // locking/mutex statement goes here
     operation1();
     operation2();
     // corresponding unlock goes here
     operation3();
}

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

可能是某种Mutex

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-03-11 16:26:09

临界区将会工作(它们是轻量级的互斥)。InitializeCriticalSection、EnterCriticalSection、LeaveCriticalSection和DeleteCriticalSection是要在MSDN上查找的函数。

代码语言:javascript
运行
复制
void func()
{
    // cs previously initialized via InitializeCriticalSection
    EnterCriticalSection(&cs);
    operation1();
    operation2();
    LeaveCriticalSection(&cs);
    operation3();}
}

编辑:临界区比互斥锁更快,因为临界区主要是用户模式原语-在非争用获取(通常是常见情况)的情况下,没有系统调用内核,而获取需要数十个周期的顺序。内核交换机的开销更大(大约需要数百个周期)。调用内核的唯一时间临界区是为了阻塞,这涉及到等待内核原语(互斥或事件)。获取互斥总是涉及到对内核的调用,因此速度要慢上几个数量级。但是,临界区只能用于同步一个进程中的资源。为了跨多个进程进行同步,需要一个互斥锁。

票数 20
EN

Stack Overflow用户

发布于 2009-03-11 17:56:06

修复上面的Michael solution

Michael solution非常适合于C应用程序。但在C++中使用时,由于可能出现异常,因此不鼓励使用这种样式。如果在operation1或operation2中发生异常,则临界区将不会正确保留,所有其他线程将阻塞等待。

代码语言:javascript
运行
复制
// 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();
}
票数 27
EN

Stack Overflow用户

发布于 2009-03-11 16:31:15

最好的方法是使用临界区,使用EnterCriticalSection和LeaveCriticalSection。唯一棘手的部分是,您需要首先用InitializeCriticalSection初始化一个临界区。如果此代码位于类中,则将初始化放入构造函数中,并将CRITICAL_SECTION数据结构作为该类的成员。如果代码不是类的一部分,您可能需要使用全局或类似的方法来确保它被初始化一次。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/635276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档