2009-10-13 23 views
1

我正在编写一个多线程应用程序。当使用Boost进程间代码(在Windows,Win32上)时,高CSwitch(“上下文切换”)

我用了boost ::进程间班(1.36.0版本)

从本质上讲,我需要在工作时可以为他们做的通知工作线程。

我尝试了“信号量”和“条件”方法。

在这两种情况下,工作线程的CSwitch(上下文切换)似乎都非常高,就像每秒600个开关一样。

我有一个在代码甘德,它似乎只是检查一个标志(原子地使用互斥体),然后在下次再次尝试之前产生时间片。

我期待的代码使用WaitForSingleObject或东西。具有讽刺意味的是,这正是我在做决定“正确”完成之前所做的,并且使用了Boost! (即使用互斥锁定期检查标志的状态)。唯一的区别是,在我的方法中,我在两次检查之间睡了50ms,所以我没有很高的CSwitch问题(对于我来说工作无法启动的时间长达50ms)。

几个问题:

  1. 这是否 “高” CSwitch值事?
  2. 如果boost库使用CRITICAL_SECTIONS而不是信号量(我不关心进程间同步 - 所有线程都在同一进程中),会发生这种情况吗?
  3. 如果boost使用WaitForSingleObject会发生这种情况吗?
  4. 是否有另一种方法在Boost库中使用前面提到的Win32等待方法(WaitForXXX),我认为它不会遭受这个CSwitch问题。

更新:这里是一个伪代码示例。我不能添加真实的代码,因为它会有点复杂。但这正是我正在做的。这只是启动一个线程来执行一次性异步活动。

注意:这些只是插图!该样本缺少负载,例如如果您在线程遇到“等待”之前调用injectWork(),它将不起作用。我只是想说明我使用boost。

用法是这样的:

int main(int argc, char** args) 
{ 
    MyWorkerThread thread; 
    thread.startThread(); 

    ... 

    thread.injectWork("hello world"); 
} 

下面是使用升压的例子。

class MyWorkerThread 
{ 
public: 

    /// Do work asynchronously 
    void injectWork(string blah) 
    { 
    this->blah = blah; 

    // Notify semaphore 
    this->semaphore->post(); 
    } 

    void startThread() 
    { 
    // Start the thread (Pseudo code) 
    CreateThread(threadHelper, this, ...); 
    } 

private: 


    static void threadHelper(void* param) 
    { 
    ((MyWorkerThread*)param)->thread(); 
    } 

    /// The thread method 
    void thread() 
    { 
    // Wait for semaphore to be invoked 
    semaphore->wait(); 

    cout << blah << endl; 
    } 

    string blah; 
    boost::interprocess::interprocess_semaphore* semaphore; 
}; 

这里是我的 “天真” 投票代码:

class MyWorkerThread_NaivePolling 
{ 
public: 

    MyWorkerThread_NaivePolling() 
    { 
    workReady = false; 
    } 

    /// Do work asynchronously 
    void injectWork(string blah) 
    { 
    section.lock(); 

    this->blah = blah; 
    this->workReady = true; 

    section.unlock(); 
    } 

    void startThread() 
    { 
    // Start the thread (Pseudo code) 
    CreateThread(threadHelper, this, ...); 
    } 

private: 

    /// Uses Win32 CriticalSection 
    class MyCriticalSection 
    { 
    MyCriticalSection(); 
    void lock(); 
    void unlock(); 
    }; 

    MyCriticalSection section; 


    static void threadHelper(void* param) 
    { 
    ((MyWorkerThread*)param)->thread(); 
    } 

    /// The thread method 
    void thread() 
    { 
    while (true) 
    { 
     bool myWorkReady = false; 
     string myBlah; 

     // See if work set 
     section.lock(); 
     if (this->workReady) 
     { 
     myWorkReady = true; 
     myBlah = this->blah; 
     } 
     section.unlock(); 

     if (myWorkReady) 
     { 
     cout << blah << endl; 
     return; 
     } 
     else 
     { 
     // No work so sleep for a while 
     Sleep(50); 
     } 
    } 
    } 

    string blah; 
    bool workReady; 
}; 

干杯,

约翰

+0

您能否在生产者和消费者线程中显示您使用的代码(对于这两种方法)? –

+0

Yup - 添加了示例代码。 – John

回答

3

在非POSIX系统上ems,看起来interprocess_condition模拟使用循环,正如你在你的问题中所描述的。并且interprocess_semaphore与互斥体和interprocess_condition一起仿真,所以wait() - 在同一个循环中结束。

既然你提到你不需要进程间同步,你应该看看Boost.Thread,它提供了一个便携式的实现condition variables。有趣的是,它似乎在Windows中以“classical”的方式实现,使用...信号量。

+0

太棒了 - 我会试试看。 – John