当前位置: 首页 > 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 

相关文章:

  • Unity 大型手游碰撞性能优化指南
  • Nginx 文件目录结构总览
  • 在WordPress上添加隐私政策页面
  • 三、OpenCV图像处理 - 图像特征提取与描述
  • 媒体报道:聚焦国产工业软件破局之道
  • PaddleOCR(1):PaddleOCR介绍
  • 【Bluedroid】蓝牙启动之gatt_init 流程源码解析
  • 质检 LIMS 系统数据防护指南 三级等保认证与金融级加密方案设计
  • CS保研面试问题
  • Edge Databases:赋能分布式计算环境
  • 【Code】Python金融基础
  • Excel高级函数使用FILTER、UNIQUE、INDEX
  • 【高校论文】DFORMER重新思考用于语义分割的RGBD表示学习[南开国防科大]
  • printf函数在调试可用但烧录后失效的全面解析与解决方案
  • 【大模型:知识图谱】--5.neo4j数据库管理(cypher语法2)
  • OpenCV C/C++ 视频播放器 (支持调速和进度控制)
  • 图片压缩工具 | 图片属性详解及读取解析元数据
  • python入门(1)
  • MySQL权限详解
  • PCB设计教程【大师篇】——产品设计流程
  • 绍兴网站网站建设/推广恶意点击软件怎样使用
  • 做电影网站要很大的主机空间吗/常州网站建设优化
  • 视频网站点击链接怎么做/视频号推广
  • 昆山网站建设公司/免费站推广网站2022
  • 网站建设和钱/徐州seo外包公司
  • 定制网站建设多少钱/小程序制作