当前位置: 首页 > news >正文

多线程与fork使用

如果一个多线程程序的某个线程调用了fork函数,那么新创建的子进程是否将自动创建和父进程相同数量的线程呢?

子进程仅保留调用fork的那个线程,其他线程在子进程中会被终止
原因:多线程环境下直接复制所有线程会引发严重的一致性问题,例如:
锁状态不一致:若父进程中某线程持有锁,子进程复制该线程会导致锁被永久占用,引发死锁。
资源竞争:多线程共享的全局变量、文件描述符等状态难以在子进程中正确还原。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static void* thread_fun(void*arg)
{sleep(1);pid_t pid;pthread_mutex_lock(&mutex);pid = fork();if(pid==0){pthread_mutex_unlock(&mutex);printf(" child \r\n");}if(pid>0){pthread_mutex_unlock(&mutex);printf(" parrent  \r\n");}printf(" thread_fun \r\n");
}int main()
{pthread_t tid;printf("hell test \r\n");if(pthread_create(&tid,NULL,thread_fun,NULL)){printf("create new thread failed\r\n");return -1;}pthread_mutex_lock(&mutex);sleep(2);pthread_mutex_unlock(&mutex);printf("main \r\n");if(pthread_join(tid,NULL))  // 等待子进程退出{printf("join thread failed \r\n");return -1;}return 0;
}
gcc thread_lock_fock.c  -o thread_atfork -lpthread

打印只有一个hell_test  说明 子进程仅保留调用fork的那个线程,其他线程在子进程中会被终止

互斥条件:锁同一时间只能被一个线程持有,pthread_mutex_lock 多次调用未解锁,将导致死锁

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static void* thread_fun(void*arg)
{sleep(1);pid_t pid;pid = fork();if(pid==0){pthread_mutex_lock(&mutex);printf(" child \r\n");pthread_mutex_unlock(&mutex);}if(pid>0){pthread_mutex_lock(&mutex);printf(" parent is%d\r\n",pid);pthread_mutex_unlock(&mutex);}printf(" thread_fun \r\n");
}int main()
{pthread_t tid;printf("hell test \r\n");if(pthread_create(&tid,NULL,thread_fun,NULL)){printf("create new thread failed\r\n");return -1;}pthread_mutex_lock(&mutex);sleep(2);pthread_mutex_unlock(&mutex);printf("main \r\n");if(pthread_join(tid,NULL))  // 等待子进程退出{printf("join thread failed \r\n");return -1;}return 0;
}
gcc thread_fork_lock.c  -o thread_atfork -lpthread
root@camera-virtual-machine:/mnt/hgfs/E/pthread# ./thread_atfork

// 子进程没法解锁 死锁

解决使用pthread_atfork函数

#include <pthread.h>int pthread_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void));
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;// 在fork前释放锁
static void prepare(void)
{printf("Prepare: Uocking mutex before fork\n");pthread_mutex_lock(&mutex);
}// fork后父进程重新加锁
static void parent(void)
{printf("Parent: Relocking mutex after fork\n");pthread_mutex_unlock(&mutex);
}// fork后子进程重置锁状态
static void child(void)
{printf("Child: Resetting mutex after fork\n");// 子进程可能需要重新初始化锁pthread_mutex_unlock(&mutex);
}static void* thread_fun(void*arg)
{sleep(1);pid_t pid;// 注册fork处理函数pthread_atfork(prepare, parent, child);pid = fork();if(pid==0){pthread_mutex_lock(&mutex);printf(" child \r\n");pthread_mutex_unlock(&mutex);}if(pid>0){pthread_mutex_lock(&mutex);printf(" parent is%d\r\n",pid);pthread_mutex_unlock(&mutex);}printf(" thread_fun \r\n");
}int main()
{pthread_t tid;printf("hell test \r\n");if(pthread_create(&tid,NULL,thread_fun,NULL)){printf("create new thread failed\r\n");return -1;}pthread_mutex_lock(&mutex);sleep(2);pthread_mutex_unlock(&mutex);printf("main \r\n");if(pthread_join(tid,NULL))  // 等待子进程退出{printf("join thread failed \r\n");return -1;}return 0;
}
root@camera-virtual-machine:/mnt/hgfs/E/pthread# gcc thread_atfork.c   -o thread_atfork -lpthread
root@camera-virtual-machine:/mnt/hgfs/E/pthread# 
root@camera-virtual-machine:/mnt/hgfs/E/pthread# 
root@camera-virtual-machine:/mnt/hgfs/E/pthread# ./thread_atfork
hell test 
Prepare: Uocking mutex before fork
main 
Parent: Relocking mutex after forkparent is3644thread_fun 
Child: Resetting mutex after forkchild thread_fun 

http://www.xdnf.cn/news/876601.html

相关文章:

  • 从繁琐到简易:3 款P图工具解锁图片编辑新体验
  • 在集成小刀knife4时报错找不到@EnableSwagger2WebMvc注解
  • 22. 括号生成【 力扣(LeetCode) 】
  • 蓝牙防丢器应用方案
  • hadoop集群单词统计(ssh与web)
  • AI助力Java开发:减少70%重复编码,实战效能提升解析
  • 如何在 git dev 中创建合并请求
  • 具备强大的数据处理和分析能力的智慧地产开源了
  • 【项目实践】SMBMS(Javaweb版)(二)登录功能
  • 《动手深度学习》8.2文本预处理—代码分析
  • Kafka消息队列笔记
  • 打包成windows exe
  • json 支持复杂结构预览、大模型服务部署体验优化|ModelWhale 版本更新
  • Ansible自动化运维全解析:从设计哲学到实战演进
  • 手写Promise中的实例方法catch
  • 如何做出更明智的选择:从吃馒头看经济学思维
  • 嵌入式学习Day32
  • 三维坐标转换
  • AXPM11584:颠覆传统,发现新可能
  • 灰狼优化算法MATLAB实现,包含种群初始化和29种基准函数测试
  • Mask篇 (含引导层、不规则遮罩)
  • 深入解析Java17核心新特性(密封类、模式匹配增强、文本块)
  • Python 类型注释 - typing
  • 关于Dify聊天对话名称无法自动生成的原因和解决方法
  • ReviewHub:实现Booster与设计工具端无缝链接的评审协作平台
  • Seata 分布式事务安装配置集成实战
  • Git忽略规则.gitignore不生效解决
  • 突破模型成本瓶颈:MoE如何让专业大模型更易用?​
  • echarts使用graph、lines实现拓扑,可以拖动增加effect效果
  • 力扣HOT100之二分查找:35. 搜索插入位置