所以,我有一个 MMO 游戏服务器正在监听连接(最多 1100 个,由于游戏设计而存在硬编码限制),并且需要在不阻塞我的主线程(处理所有虚拟世界逻辑)的情况下记录所有内容,包括但不包括仅限于:NPC 向玩家提供的内容、怪物/玩家死亡时、每条聊天消息、玩家升级时、玩家将元素掉落在地上时等。
我从每个连接的池中获取一个线程,每个线程都可以随时登录到文件(实际上可能永远不会发生,但服务器必须做好足够的准备以适本地处理它)。
我想到了一个独立的日志线程不断检查订单队列,直到它不为空。
while Game is Running
Check the queue, if it's empty, sleep.
File IO. Open plain-text file, log and gracefully close it.
Repeat.
链表是否足以组织队列并使用这样的互斥锁来保护它?
LogThreadOrder Queue[1024];
LogThreadOrder *FirstThreadOrder;
int NumberOfOrders;
struct LogThreadOrder {
char FileName[4096];
char LogMessage[4096];
LogThreadOrder* NextOrder;
};
void Log(const char* FileName, const char* LogMessage) {
LogMutex.lock();
ProtocolThreadOrder* Order = Queue[NumberOfOrders++];
Order->NextOrder = FirstThreadOrder;
FirstThreadOrder = Order;
LogMutex.release();
}
int LogThreadLoop() {
// Loop through Queue until its empty.
}
所以,我的问题是:
这是一个聪明的设计吗?
线程安全吗?
有没有更好的方法来完成我想做的事情?
拥有多个记录器线程和多个队列会更好/更高效吗?
最佳答案
你的伪代码可以工作,但在 C 语言中很难,而且互斥同步效率低下。根据我的经验,使用现有的、完善的异步总是更好 inter-process communication线程之间的机制如 named pipes 。即使如此,仍然存在许多陷阱,并且当依赖关系不是问题时,使用 ZeroMQ 之类的东西可能是最好的主意。具体来说像 this 。我认为拥有多个线程不是一个好主意,因为您要写入的文件将成为一个争用点。
关于c - C 中 Logger 线程的线程安全队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57212149/