news 2026/6/15 14:30:04

Linux网络编程踩坑:多线程并发服务器中文件描述符的正确传递方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux网络编程踩坑:多线程并发服务器中文件描述符的正确传递方式

在编写多线程并发服务器(Multi-threaded Server)时,最容易让新手“翻车”的一个细节就是如何将主线程接收到的文件描述符(File Descriptor, fd)正确地传递给子线程

很多初学者会发现,明明代码逻辑看起来没问题,但当多个客户端同时连接时,消息却发错乱了(比如客户端A发的消息被服务器回传给了客户端B)。本文将基于课堂笔记,深度解析这个经典的“内存共享陷阱”,并提供正确的解决方案。

一、 问题背景:为什么不能直接传地址?

1. 典型错误场景

在主线程的while循环中,我们通常会这样做:

  1. 调用accept()阻塞等待,返回一个新的文件描述符cfd
  2. 调用pthread_create()创建子线程。
  3. 错误操作:将cfd的地址(&cfd)作为参数传递给子线程。

2. 原因深度剖析

这涉及到了进程与线程的内存模型差异

  • 进程(Process):拥有独立的虚拟地址空间。修改一个进程的变量不会影响另一个进程(写时复制)。
  • 线程(Thread):共享同一个进程的虚拟地址空间(堆、全局变量等)。

灾难发生的流程如下:

  1. 时刻 T1:主线程accept成功,cfd变量被赋值为3(代表客户端 A)。
  2. 时刻 T2:主线程调用pthread_create,传入&cfd
  3. 时刻 T3:主线程继续循环,再次accept成功,cfd变量被更新为4(代表客户端 B)。
  4. 时刻 T4:子线程 A 开始运行,通过传入的地址&cfd去读取数据。此时它读到的是被修改后的值 4

结果:子线程 A 本该服务客户端 A(fd=3),结果却拿到了 fd=4,导致它错误地与客户端 B 进行了通信,或者发生“串台”现象。


二、 解决方案:构建描述符管理数组

为了避免上述竞态条件(Race Condition),我们需要保证每个子线程拿到的文件描述符是存储在独立内存区域中的,互不干扰。

核心思路:

  1. 定义一个全局结构体数组(或整型数组)。
  2. 主线程accept成功后,遍历数组找到一个“空闲位置”。
  3. cfd存入该位置。
  4. 该数组元素的地址传递给子线程。

这样,即使主线程的cfd局部变量变了,数组中存储的值也不会变。


三、 代码实战

下面是一个完整的、可运行的多线程并发服务器代码案例。

1. 代码实现 (server_fixed.c)

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<arpa/inet.h>#include<pthread.h>#include<ctype.h>#defineMAX_CONN1024#definePORT8888// 定义一个结构体来存储每个连接的信息structSockInfo{intfd;// 通信文件描述符structsockaddr_inaddr;// 客户端地址信息(可选,方便日志打印)};// 全局数组,用于管理所有连接// 初始化时需要将fd设为-1,表示空闲structSockInfoinfos[MAX_CONN];// 子线程的工作函数void*worker(void*arg){// 1. 将参数强转回结构体指针structSockInfo*pinfo=(structSockInfo*)arg
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 10:27:37

douyin-downloader高效获取指南:从零基础到专家级管理

douyin-downloader高效获取指南&#xff1a;从零基础到专家级管理 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader douyin-downloader是一款专注于抖音内容批量获取与智能管理的工具&#xff0c;通过自动化技…

作者头像 李华
网站建设 2026/6/15 13:25:08

抖音直播回放高效下载与智能管理完全指南

抖音直播回放高效下载与智能管理完全指南 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 你是否曾为错过精彩的抖音直播而遗憾&#xff1f;是否想保存喜爱主播的直播内容以便日后回味&#xff1f;本文将带你…

作者头像 李华
网站建设 2026/6/15 11:48:42

3个核心方案提升Mac游戏操控体验:跨平台按键映射与手柄配置指南

3个核心方案提升Mac游戏操控体验&#xff1a;跨平台按键映射与手柄配置指南 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover Mac游戏操控优化是提升手游体验的关键环节&#xff0c;而跨平台按键映射技术…

作者头像 李华