项目一(线程邮箱)

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(销毁);

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

相关推荐
2601_962295993 小时前
嵌入式开发语言用哪个最好,C,python或者其他
c语言·python·嵌入式开发·开发效率·系统资源
是隼人6 小时前
buuctf-pwn [HarekazeCTF2019]baby_rop2(64位ret2libc)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
wuyk5557 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
AAA代码批发商9 小时前
Days 39 Linux C 开发之 SQLite 数据库完整学习笔记
linux·c语言·数据库
卢锡荣11 小时前
单芯掌控多口互联|乐得瑞 LDR6020 PD3.1 多通道 Type‑C 控制 SOC 芯片
c语言·开发语言
wuminyu11 小时前
JVM锁膨胀与Futex源码解析
java·linux·c语言·jvm·c++
susplus11 小时前
【HTTP协议】HTTP介绍及基础【C语言爬虫实现】
c语言·爬虫·http·万维网
xx~t12 小时前
嵌入式——Linux软件编程——数据库
linux·c语言·数据库·oracle·sqlite
水饺编程12 小时前
第5章,[Win32 章节] :圆角矩形教学插图绘制程序
c语言·c++·windows·visual studio
是隼人12 小时前
buuctf-pwn PWN4(双引号的转义缺陷)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门