首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

進程池多進程服務器:信號衝突導致任務丟失的解決方案

     編輯:程式設計疑難解答

問題核心

主進程 accept 後發送 SIGUSR1 通知控制進程,高併發下信號可能合併/丟失,導致控制進程漏讀管道中的連接套接字。

根本原因

Linux 標準信號不排隊:同一信號多次發送給進程,若進程正在處理該信號或信號被阻塞,後續信號會被丟棄(僅保留一個 pending)。

解決方案

  1. 使用實時信號(SIGRTMIN+):實時信號支持排隊,不丟失。
    kill(control_pid, SIGRTMIN); // 替代 SIGUSR1
    
  2. 管道/事件 fd 替代信號:主進程將連接 fd 寫入管道,控制進程 epoll 監聽管道讀端,完全避免信號。
    // 主進程
    write(pipe_fd[1], &conn_fd, sizeof(conn_fd));
    // 控制進程 epoll 事件循環讀取 pipe_fd[0]
    
  3. 信號處理函數中僅設置標誌位,主循環輪詢標誌位並處理所有待讀數據(需配合 sigprocmask 解除阻塞)。
  4. 推薦架構

    採用 主進程 accept + epoll 分發 或 線程池,簡化信號處理。參考 經典進程池模型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved