Linux下用clone()实现多线程时的重复打印问题排查
pthread库自带标准IO线程安全保护
POSIX标准要求pthread环境下的printf这类标准IO函数是线程安全的。glibc实现的pthread库会给每个标准流(比如stdout)内部加上互斥锁,确保单个printf调用的整个输出过程是原子的——一个线程在执行printf时,其他线程的printf会被阻塞,直到前一个完成。这样哪怕多个线程同时打印,也不会出现字符交错、重复的情况。而你用
clone()手动创建线程时,如果程序没链接pthread库,glibc的标准IO模块会保持单线程模式,不会启用这些内部锁。多个线程同时操作stdout的用户态缓冲区时,就可能出现缓冲区数据混乱,进而导致重复打印或者输出错乱。clone()的参数与资源共享细节差异
pthread创建线程时,默认会正确设置所有必要的资源共享标志(比如CLONE_VM、CLONE_FILES、CLONE_THREAD等),同时会初始化线程本地存储(TLS)、信号处理隔离等线程环境。而你自己用clone()时,如果参数设置不全或者缺少某些环境初始化步骤,可能导致线程间的资源共享状态和pthread线程不一致,比如没有正确同步标准IO的缓冲状态,多个线程的输出操作更容易互相干扰。线程调度与初始化的差异
pthread_create在创建线程时会做一系列调度相关的初始化,比如设置合理的线程优先级、调度策略,确保线程的启动时机相对有序。而直接用clone()创建的线程可能会立即抢占当前线程执行,导致多个线程同时进入printf的概率更高,更容易触发竞争条件,暴露输出混乱的问题。
内容的提问来源于stack exchange,提问作者jiaqi

