项目一(线程邮箱)

1.线程邮箱系统框图

2.主要函数步骤

创建MBS---->注册线程---->等待mbs结束---->销毁邮箱系统

复制代码
1.g_mbs = create_mail_box_system();
2.register_to_mail_system(g_mbs, "show", show_th);
3.wait_all_end(g_mbs);
4.destroy_mail_box_system(g_mbs);

MBS的创建并初始化

cpp 复制代码
MBS*create_mail_box_system()
{
   MBS*m_mbs = malloc(sizeof(MBS));
   if(NULL == m_mbs)
   {
      perror("create error");
      return NULL;
   }
   INIT_LIST_HEAD(&m_mbs->head);
   pthread_mutex_init(&m_mbs->mutex,NULL);
   return m_mbs;
}

创建节点并注册

cpp 复制代码
int register_to_mail_system(MBS*mbs,char name[],th_fun th)
{
    LIST_DATA*list_node=malloc(sizeof(LIST_DATA)); // 分配用户节点内存
    if(NULL == list_node) 
    {
        perror("register malloc");
        return 1;
    }
    strcpy(list_node->name,name); // 复制用户名
    list_node->lq=CreateLinkQue(); // 为该用户创建专属消息队列
    list_add(&list_node->node,&mbs->head); // 将节点添加到MBS的链表中
    pthread_create(&list_node->tid,NULL,th,NULL); // 创建用户对应的线程
    return 0;
}

等待结束

cpp 复制代码
int wait_all_end(MBS*mbs)
{
    LIST_DATA *pos, *q;
    // 安全遍历链表(遍历时可能删除节点,q用于保存下一个节点)
    list_for_each_entry_safe(pos, q, &mbs->head, node)
    {
        pthread_join(pos->tid, NULL); // 等待该用户线程结束
    }
    return 0;
}

按名称/线程id查找用户节点

cpp 复制代码
LIST_DATA* find_node_byname(MBS* mbs, char* name)
{
    LIST_DATA *pos, *q;
    list_for_each_entry_safe(pos, q, &mbs->head, node)
    {
        if (0 == strcmp(pos->name, name)) // 字符串匹配
        {
            return pos; // 找到则返回节点
        }
    }
    return NULL; // 未找到返回NULL
}
cpp 复制代码
LIST_DATA* find_node_byid(MBS* mbs, pthread_t id)
{
    LIST_DATA *pos, *q;
    list_for_each_entry_safe(pos, q, &mbs->head, node)
    {
        if (pos->tid == id) // 线程ID匹配
        {
            return pos;
        }
    }
    return NULL;
}

发送消息

cpp 复制代码
int send_msg(MBS* mbs, char* recvname, MAIL_DATA* data)
{
    // 1. 找到发送者自身节点(通过当前线程ID)
    LIST_DATA* myself = find_node_byid(mbs, pthread_self());
    if (NULL == myself)
    {
        fprintf(stderr, "sendmsg error ,find myself id\n");
        return 1;
    }
    // 2. 填充发送者信息到邮件
    data->id_of_sender = pthread_self();
    strcpy(data->name_of_sender, myself->name);

    // 3. 找到接收者节点(通过接收者名称)
    LIST_DATA* recver = find_node_byname(mbs, recvname);
    if (NULL == recver)
    {
        fprintf(stderr, "sendmsg error ,find recver name\n");
        return 1;
    }

    // 4. 填充接收者信息到邮件
    data->id_of_recver = recver->tid;
    strcpy(data->name_of_recver, recver->name);

    // 5. 加锁后将邮件放入接收者的消息队列
    pthread_mutex_lock(&mbs->mutex);
    EnterLinkQue(recver->lq, data);
    pthread_mutex_unlock(&mbs->mutex);
    return 0;
}

接收消息

cpp 复制代码
int recv_msg(MBS* mbs, MAIL_DATA* data)
{
    // 1. 找到接收者自身节点
    LIST_DATA* myself = find_node_byid(mbs, pthread_self());
    if (NULL == myself)
    {
        fprintf(stderr, "recv_msg find_node_byid myself\n");
        return 0;
    }

    pthread_mutex_lock(&mbs->mutex);
    // 2. 获取消息队列队头(不删除)
    MAIL_DATA* tmp = GetHeadLinkQue(myself->lq);
    if (NULL == tmp) // 队列为空,无消息
    {
        pthread_mutex_unlock(&mbs->mutex);
        return 1;
    }
    // 3. 复制消息到输出参数data
    memcpy(data, tmp, sizeof(MAIL_DATA));
    // 4. 出队(删除队头)
    QuitLinkQue(myself->lq);
    pthread_mutex_unlock(&mbs->mutex);

    return 0;
}

销毁邮箱系统

cpp 复制代码
void destroy_mail_box_system(MBS* mbs)
{
    LIST_DATA *pos, *q;

    list_for_each_entry_safe(pos, q, &mbs->head, node)
    {
        list_del(&pos->node);
        free(pos);
    }

    return;
}

总结:

核心逻辑:基于 Linux 内核链表管理用户节点,每个用户绑定线程和独立消息队列,通过互斥锁保证多线程消息收发的安全性;

核心函数:create_mail_box_system(创建)→register_to_mail_system(注册)→send_msg/recv_msg(收发消息)→wait_all_end(等待线程)→destroy_mail_box_system(销毁);

关键优化点:补充内存释放、加锁遍历链表、替换不安全字符串操作、完善错误检查。

相关推荐
历程里程碑4 小时前
Linxu14 进程一
linux·c语言·开发语言·数据结构·c++·笔记·算法
JiL 奥5 小时前
Nexus制品归档(c/c++项目)
c语言·c++
梵刹古音5 小时前
【C语言】 字符型变量
c语言·开发语言·嵌入式
wengqidaifeng5 小时前
探索数据结构(二):空间复杂度
c语言·开发语言·数据结构
皮皮哎哟6 小时前
夯实基础:数据结构核心概念与线性表(顺序表&链表)C语言全解析 数据结构篇
c语言·数据结构·顺序表·单向链表·有头链表
划破黑暗的第一缕曙光7 小时前
[数据结构]:4.二叉树_堆
c语言·数据结构·二叉树·
浅念-7 小时前
C语言——双向链表
c语言·数据结构·c++·笔记·学习·算法·链表
wengqidaifeng8 小时前
数据结构---顺序表的奥秘(下)
c语言·数据结构·数据库
m0_748233179 小时前
C语言vsC#:核心差异全解析
c语言·开发语言·c#
Sunsets_Red10 小时前
单调队列优化dp
c语言·c++·算法·c#·信息学竞赛