c - C 中 Logger 线程的线程安全队列

标签 c multithreading synchronization pthreads

所以,我有一个 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/

相关文章:

c - 使用两个按钮去抖,用 Arduino 打开不同的 LED

c GTK3 文本应向上滚动而不是隐藏

c++ - 二锁并发队列算法问题

java - 为什么 Fortify 将其标记为未发布的资源?

mongodb - 客户端之间的数据同步

c - malloc.c 中的断言 :2453

c - C中的二维字符数组

c# - 有没有一种方法可以使正在运行的方法通过 cts.Cancel(); 立即停止?

java - 如何停止在 Java 中的阻塞读取操作中等待的线程?

java - 从基于 Swing 的应用程序中的线程(ETC 除外)接收更新