news 2026/6/25 7:34:26

DAY46 Thread Mailbox System (C Language + Multi-thread Communication)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DAY46 Thread Mailbox System (C Language + Multi-thread Communication)

Thread Mailbox System (C Language + Multi-thread Communication)

1. Core Positioning and Advantages

1.1 Core Objective

Enable asynchronous message passing between threads, allowing threads to communicate indirectly via “mailboxes” instead of direct interaction. This reduces logical coupling between threads while ensuring thread safety and data integrity in communication.

1.2 Key Advantages

  • Low Coupling: Threads only need to send/receive messages via mailbox names without knowing other threads’ IDs or logic. Modifying a single thread does not affect the overall system.
  • Easy Scalability: Adding new threads only requires registration to the mailbox system without modifying existing thread code.
  • Thread Safety: Critical resources are protected by mutex locks (pthread_mutex_t) to avoid concurrent access conflicts.
  • Lightweight: Implemented using native C and kernel-linked lists with no third-party dependencies, ensuring minimal resource usage.
  • Flexible Adaptation: Supports one-to-one or one-to-many message passing between arbitrary threads, with customizable message formats.

2. Core Architecture and Data Structures

1. Overall Architecture Diagram (Based on PDF Analysis)

┌─────────────────────────────────────────────────────────┐ │ Thread Mailbox System (MBS) │ │ ┌─────────────┐ ┌───────────┐ ┌─────────────────┐ │ │ │ Link Head (link_head) │ Mutex Lock (mutex) │ Thread Node List (LIST_DATA) │ │ │ └─────────────┘ └───────────┘ └─────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌───────────┐ ┌─────────────────┐ │ │ │ Thread A (data) │ Thread B (show) │ Thread C (sock) │ │ │ │ - Name: data │ - Name: show │ - Name: sock │ │ │ │ - Thread ID: tid│ - Thread ID: tid│ - Thread ID: tid │ │ │ │ - Message Queue │ - Message Queue │ - Message Queue │ │ │ │ - Thread Function│ - Thread Function│ - Thread Function │ │ │ └─────────────┘ └───────────┘ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌───────────┐ ┌─────────────────┐ │ Send Message │ │ Receive Message │ │ Receive Message │ │ Send_msg("show", data) │ Recv_msg() │ Recv_msg() │ │ Send_msg("sock", data) │ Print Message │ Print Message │ └─────────────┘ └───────────┘ └─────────────────┘

2. Core Data Structure Analysis

(1) Mailbox System Core Structure (MBS)
typedefstructmail_box_system{pthread_mutex_tmutex;// Protects critical resources (message queues, thread lists)structlist_headhead;// Thread node list head (reuses Linux kernel doubly linked list)}MBS;
  • mutex: Mutex lock ensuring thread safety during concurrent access.
  • head: Doubly linked list head managing all thread nodes registered in the mailbox system.
(2) Thread Node Structure (LIST_DATA)

Each thread registered in the mailbox system corresponds to a node storing core thread information:

typedefstructthread_node{pthread_ttid;// Thread IDcharname[256];// Unique thread name (for message addressing)LinkQue*lq;// Thread-specific message queue (stores received messages)th_fun th;// Thread function pointerstructlist_headnode;// Linked list node (connects to MBS's head list)}LIST_DATA;
(3) Message Structure (MAIL_DATA)

Message format for inter-thread communication, extendable as needed:

typedefstructmail_data{pthread_tid_of_sender;// Sender thread IDcharname_of_sender[256];// Sender thread namepthread_tid_of_recver;// Receiver thread IDcharname_of_recver[256];// Receiver thread namechardata[256];// Message content (extendable to any data type)}MAIL_DATA;
(4) Linked Queue Structure (LinkQue)

Used to store thread messages, implementing FIFO (First-In-First-Out) message delivery:

typedefstructquenode{DATATYPE data;// Message data (DATATYPE = MAIL_DATA)structquenode*next;// Next message node}LinkQueNode;typedefstruct_linkque{LinkQueNode*head;// Queue headLinkQueNode*tail;// Queue tailintclen;// Number of messages in the queue}LinkQue;

3. Core Function Implementation (Based on Code Breakdown)

The core workflow of the system is: “Create Mailbox System → Thread Registration → Message Sending/Receiving → System Destruction.” Below is a detailed breakdown of the key functional implementations.

1. Initialize Mailbox System (create_mail_box_system)

MBS*create_mail_box_system(){MBS*m_mbs=malloc(sizeof(MBS));if(NULL==m_mbs){perror("malloc failed");returnNULL;}INIT_LIST_HEAD(&m_mbs->head);// Initialize doubly linked list headpthread_mutex_init(&m_mbs->mutex,NULL);// Initialize mutex lockreturnm_mbs;}
  • Core Purpose: Allocates memory for the mailbox system, initializes the thread linked list and mutex lock, preparing for subsequent thread registration and message passing.
  • Key Technique:INIT_LIST_HEADis a Linux kernel macro for initializing linked lists, setting thenextandprevpointers of the list head to point to itself, forming an empty list.

2. Thread Registration (register_to_mail_system)

Threads must register with the mailbox system before sending/receiving messages:

intregister_to_mail_system(MBS*mbs,charname[],th_fun th){// 1. Allocate memory for thread nodeLIST_DATA*list_node=malloc(sizeof(LIST_DATA));if(NULL==list_node){perror("malloc failed");return1;}// 2. Initialize node info (name, message queue)strcpy(list_node->name,name);list_node->lq=CreateLinkQue();// Create dedicated message queue// 3. Add node to the thread linked list of the mailbox systemlist_add(&list_node->node,&mbs->head);// 4. Create thread (execute the passed thread function th)pthread_create(&list_node->tid,NULL,th,NULL);return0;}
  • Core Purpose: Creates a dedicated message queue for the thread, connects the thread node to the system linked list, and starts the thread.
  • Key Technique: Thelist_addmacro inserts the thread node after the list head, enabling efficient node addition.

3. Message Sending (send_msg)

Threads send messages via the recipient’s name without needing to know the recipient’s thread ID:

intsend_msg(MBS*mbs,char*recvname,MAIL_DATA*data){// 1. Locate sender's own node (via current thread ID)LIST_DATA*myself=find_node_byid(mbs,pthread_self());if(NULL==myself){fprintf(stderr,"find sender failed");return1;}// 2. Fill sender info in the messagedata->id_of_sender=pthread_self();strcpy(data->name_of_sender,myself->name);// 3. Locate recipient node (via recipient name)LIST_DATA*recver=find_node_byname(mbs,recvname);if(NULL==recver){fprintf(stderr,"find recver failed");return1;}// 4. Fill recipient info in the messagedata->id_of_recver=recver->tid;strcpy(data->name_of_recver,recver->name);// 5. Lock and enqueue the message (thread-safe)pthread_mutex_lock(&mbs->mutex);EnterLinkQue(recver->lq,data);// Enqueue message to recipient's queuepthread_mutex_unlock(&mbs->mutex);return0;}
  • Core Purpose: Encapsulates sender and recipient info, safely adding the message to the recipient’s message queue.
  • Thread Safety: Usespthread_mutex_lock/unlockto protect the enqueue operation, preventing concurrent write conflicts.

4. Message Receiving (recv_msg)

Threads read messages from their own message queues for asynchronous reception:

intrecv_msg(MBS*mbs,MAIL_DATA*data){// 1. Locate current thread's nodeLIST_DATA*myself=find_node_byid(mbs,pthread_self());if(NULL==myself){fprintf(stderr,"find self failed");return1;}// 2. Lock and read the message at the head of the queuepthread_mutex_lock(&mbs->mutex);MAIL_DATA*tmp=GetHeadLinkQue(myself->lq);if(NULL==tmp){// Queue empty, unlock and returnpthread_mutex_unlock(&mbs->mutex);return1;}// 3. Copy message to receive buffer, remove it from the queuememcpy(data,tmp,sizeof(MAIL_DATA));QuitLinkQue(myself->lq);// Dequeue messagepthread_mutex_unlock(&mbs->mutex);return0;}
  • Core Purpose: Reads messages from the thread’s dedicated queue in FIFO order.
  • No-Message Handling: Returns 1 if the queue is empty; threads can retry with a loop + sleep to avoid busy waiting.

5. System Destruction and Resource Release (destroy_mail_box_system)

voiddestroy_mail_box_system(MBS*mbs){LIST_DATA*pos,*q;// Traverse all thread nodes, delete and release resourceslist_for_each_entry_safe(pos,q,&mbs->head,node){list_del(&pos->node);// Remove node from the listfree(pos);// Free node memory}return;}
  • Key Technique:list_for_each_entry_safeis a kernel macro for safe traversal, using temporary variableqto store the next node, preventing list breakage after deleting the current node.

IV. Practical Usage Example (Based on main.c)

Below is a complete example demonstrating the workflow of the thread mailbox system: system creation → thread registration → message sending/receiving.

1. Thread Function Implementation

(1) Data Generation Thread (data_th)

Periodically generates simulated sensor data and sends it toshowandsockthreads:

void*data_th(void*arg){srand(time(NULL));MAIL_DATA data;while(1){// Generate simulated data between 30.00~39.99intnum=rand()%1000+3000;floattmp=num/100.0;bzero(&data,sizeof(data));sprintf(data.data,"temp:%.2f°C",tmp);// Message content// Send message to "show" threadsend_msg(g_mbs,"show",&data);sleep(rand()%3);// Random sleep 0~2 seconds// Send message to "sock" threadsend_msg(g_mbs,"sock",&data);sleep(rand()%2);// Random sleep 0~1 second}returnNULL;}
(2) Message Display Thread (show_th)

Continuously receives and prints messages:

void*show_th(void*arg){MAIL_DATA data;while(1){bzero(&data,sizeof(data));intret=recv_msg(g_mbs,&data);if(1==ret){sleep(1);continue;}// Sleep if no message// Print received messageprintf("[show thread] Received message from %s: %s\n",data.name_of_sender,data.data);}returnNULL;}
(3) Network Sending Thread (sock_th)

Simulates sending messages over the network (simplified as printing here):

void*sock_th(void*arg){MAIL_DATA data;while(1){bzero(&data,sizeof(data));intret=recv_msg(g_mbs,&data);if(1==ret){sleep(1);continue;}// Sleep if no message// Simulate network sendingprintf("[sock thread] Received message from %s (to be sent over network): %s\n",data.name_of_sender,data.data);}returnNULL;}

2. Main Function (Program Entry)

MBS*g_mbs;// Global mailbox system pointer (for easy access by thread functions)intmain(intargc,char**argv){// 1. Create mailbox systemg_mbs=create_mail_box_system();// 2. Register 3 threads: show, sock, dataregister_to_mail_system(g_mbs,"show",show_th);register_to_mail_system(g_mbs,"sock",sock_th);register_to_mail_system(g_mbs,"data",data_th);// 3. Wait for all threads to finish (blocking main thread)wait_all_end(g_mbs);// 4. Destroy mailbox system and release resourcesdestroy_mail_box_system(g_mbs);return0;}

3. Compilation and Execution

(1) Compilation Command (Requires linking pthread library)
gcc main.c mailbox.c linkque.c-othread_mailbox-lpthread
(2) Sample Execution Output
[show thread] Received message from data: temp:32.56°C [sock thread] Received message from data (to be sent over network): temp:32.56°C [show thread] Received message from data: temp:37.12°C [sock thread] Received message from data (to be sent over network): temp:35.89°C ...

V. Design Highlights and Technical Details

1. Reusing Linux Kernel Linked List (list.h)

  • Advantage: The kernel linked list is a proven efficient data structure that supports fast insertion, deletion, and traversal without manual implementation;
  • Key Macros:list_add(add node),list_del(delete node),list_for_each_entry_safe(safe traversal), simplifying thread node management.

2. Thread-Safe Design

  • Mutex (pthread_mutex_t): Protects concurrent access to the thread list and message queue, preventing data corruption from simultaneous multi-thread modifications;
  • Message Queue Isolation: Each thread has its own message queue, avoiding message confusion and reducing lock contention.

3. Low-Coupling Design

  • Thread Addressing: Uses thread names instead of IDs to find recipients, with thread IDs assigned by the system, making names easier to maintain;
  • Message Encapsulation: TheMAIL_DATAstructure standardizes message format, allowing senders and receivers to ignore each other’s implementation details;
  • Flexible Extension: New threads only need to callregister_to_mail_systemwithout modifying existing thread code.

VI. Extension Directions and Applicable Scenarios

1. Functional Extensions

  • Message Priority: Add apriorityfield toMAIL_DATAto sort message queues by priority, supporting urgent message processing;
  • Timeout Reception: Extendrecv_msgto support timeout settings, preventing infinite thread blocking;
  • Dynamic Deregistration: Addunregister_from_mail_systemto allow threads to exit the mailbox system during runtime;
  • Message Receipt: Add a message delivery confirmation mechanism to ensure messages are received.

2. Applicable Scenarios

  • Embedded Systems: Message passing from sensor data collection threads → data processing threads → network sending threads;
  • Multi-Module Collaboration: For example, in a web server, request receiving threads → business processing threads → response sending threads;
  • Logging Systems: Multiple business threads send log messages to a logging thread for unified printing or file writing.
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 12:58:20

快速理解Pspice开关电源热效应仿真核心要点

深入掌握Pspice开关电源热仿真:从MOSFET温升到系统级热耦合的实战解析你有没有遇到过这样的情况?电路设计看起来完美无瑕,波形干净利落,效率计算也达标——可一上电满载运行几分钟,主MOSFET就“啪”地一声烧掉了。拆下…

作者头像 李华
网站建设 2026/6/18 5:18:43

VibeVoice能否生成会议纪要语音版?办公自动化场景

VibeVoice能否生成会议纪要语音版?办公自动化场景 在现代企业中,一场两小时的会议结束后,往往伴随着一份长达十几页的文字纪要。员工需要花上半小时逐字阅读,才能理清讨论脉络——这不仅效率低下,还容易遗漏语气、停顿…

作者头像 李华
网站建设 2026/6/15 12:20:02

模拟电路设计基础:电子电路核心要点解析

模拟电路设计的本质:从放大、偏置到稳定性的实战解析你有没有遇到过这样的情况?精心搭建的放大电路,输入一个干净的小信号,结果输出波形却“抽搐”不止——不是削顶就是自激振荡。测电源电流时发现温升明显,甚至芯片发…

作者头像 李华
网站建设 2026/6/22 4:11:12

VibeVoice-WEB-UI使用指南:零基础也能玩转多说话人语音合成

VibeVoice-WEB-UI使用指南:零基础也能玩转多说话人语音合成 在播客、有声书和虚拟会议日益普及的今天,一个现实问题摆在内容创作者面前:如何高效生成自然流畅、角色分明的多人对话音频?传统文本转语音(TTS)…

作者头像 李华
网站建设 2026/6/25 12:07:10

VibeVoice能否应用于有声书制作?长篇小说适配性分析

VibeVoice能否应用于有声书制作?长篇小说适配性分析 在数字内容消费日益“听觉化”的今天,有声书市场正以每年超过20%的增速扩张。然而,传统制作模式依赖专业配音演员、录音棚和漫长的后期流程,导致成本高企、周期冗长。一个典型1…

作者头像 李华
网站建设 2026/6/13 20:39:18

10分钟用快马平台搭建MODBUS通信原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 快速开发一个MODBUS通信原型,模拟主站(Master)与从站(Slave)的基本通信。主站发送读取保持寄存器的请求(功能…

作者头像 李华