我正在编写一个多线程应用程序。当使用Boost进程间代码(在Windows,Win32上)时,高CSwitch(“上下文切换”)
我用了boost ::进程间班(1.36.0版本)
从本质上讲,我需要在工作时可以为他们做的通知工作线程。
我尝试了“信号量”和“条件”方法。
在这两种情况下,工作线程的CSwitch(上下文切换)似乎都非常高,就像每秒600个开关一样。
我有一个在代码甘德,它似乎只是检查一个标志(原子地使用互斥体),然后在下次再次尝试之前产生时间片。
我期待的代码使用WaitForSingleObject或东西。具有讽刺意味的是,这正是我在做决定“正确”完成之前所做的,并且使用了Boost! (即使用互斥锁定期检查标志的状态)。唯一的区别是,在我的方法中,我在两次检查之间睡了50ms,所以我没有很高的CSwitch问题(对于我来说工作无法启动的时间长达50ms)。
几个问题:
- 这是否 “高” CSwitch值事?
- 如果boost库使用CRITICAL_SECTIONS而不是信号量(我不关心进程间同步 - 所有线程都在同一进程中),会发生这种情况吗?
- 如果boost使用WaitForSingleObject会发生这种情况吗?
- 是否有另一种方法在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;
};
干杯,
约翰
您能否在生产者和消费者线程中显示您使用的代码(对于这两种方法)? –
Yup - 添加了示例代码。 – John