我想在进程内运行多个线程。我正在寻找能够在线程之间传递消息的最有效方法。
每个线程都有一个共享内存输入消息缓冲区。其他线程会写入适当的缓冲区。
消息优先。我想自己管理这个过程。
没有昂贵的锁定或同步,最好的方法是什么?或者是否已经有一个久经考验的图书馆? (Delphi,C或C#很好)。
答案 0 :(得分:2)
如果不重复其他人已经为你做出的许多错误,这很难做到:)
看一下Intel Threading Building Blocks - 图书馆有几个精心设计的队列模板(以及其他馆藏),您可以测试并找出最适合您的目的。
答案 1 :(得分:1)
如果要使用多个线程,则很难避免同步。幸运的是,这并不是很难。
对于单个流程,临界区通常是最佳选择。它快速且易于使用。为简单起见,我通常将其包装在一个类中以处理初始化和清理。
#include <Windows.h>
class CTkCritSec
{
public:
CTkCritSec(void)
{
::InitializeCriticalSection(&m_critSec);
}
~CTkCritSec(void)
{
::DeleteCriticalSection(&m_critSec);
}
void Lock()
{
::EnterCriticalSection(&m_critSec);
}
void Unlock()
{
::LeaveCriticalSection(&m_critSec);
}
private:
CRITICAL_SECTION m_critSec;
};
使用锁定/解锁它的“自动锁定”类可以使它更简单。
class CTkAutoLock
{
public:
CTkAutoLock(CTkCritSec &lock)
: m_lock(lock)
{
m_lock.Lock();
}
virtual ~CTkAutoLock()
{
m_lock.Unlock();
}
private:
CTkCritSec &m_lock;
};
要锁定某些内容的任何地方,实例化自动锁定。功能完成后,它将解锁。此外,如果存在异常,它将自动解锁(提供异常安全性)。
现在,您可以从标准优先级队列中创建一个简单的消息队列
#include <queue>
#include <deque>
#include <functional>
#include <string>
struct CMsg
{
CMsg(const std::string &s, int n=1)
: sText(s), nPriority(n)
{
}
int nPriority;
std::string sText;
struct Compare : public std::binary_function<bool, const CMsg *, const CMsg *>
{
bool operator () (const CMsg *p0, const CMsg *p1)
{
return p0->nPriority < p1->nPriority;
}
};
};
class CMsgQueue :
private std::priority_queue<CMsg *, std::deque<CMsg *>, CMsg::Compare >
{
public:
void Push(CMsg *pJob)
{
CTkAutoLock lk(m_critSec);
push(pJob);
}
CMsg *Pop()
{
CTkAutoLock lk(m_critSec);
CMsg *pJob(NULL);
if (!Empty())
{
pJob = top();
pop();
}
return pJob;
}
bool Empty()
{
CTkAutoLock lk(m_critSec);
return empty();
}
private:
CTkCritSec m_critSec;
};
CMsg的内容可以是您喜欢的任何内容。请注意,CMsgQue从std :: priority_queue继承私有。这可以防止在不通过我们的(同步)方法的情况下对队列进行原始访问。
将这样的队列分配给每个线程,您就在路上。
免责声明这里的代码被快速打了一下,以说明一点。在用于生产之前,它可能存在错误并需要检查和测试。