邢台市网站建设_网站建设公司_Sketch_seo优化
2026/1/16 15:21:52 网站建设 项目流程

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.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询