c++ fork 进程时 共享内存_Windows下的PostgreSQL进程fork

Windows系统API我并不熟悉,所以本篇大致点出过程,更多细节还请阅读代码和详查微软文档。后边还会有一篇讲Windows下信号处理的模拟,内容跟这篇是关联的。

这篇文章假定读者已经了解*nix的fork,如果不了解,请自行阅读相关资料。

1、*nix下PG后端(backend)进程的发起:

static intBackendStartup(Port *port){...#ifdef EXEC_BACKEND  pid = backend_forkexec(port);#else             /* !EXEC_BACKEND */  pid = fork_process();  if (pid == 0)       /* child */{...

当然这里还有一些其他逻辑,不细表,有兴趣可以自己瞅瞅,都不复杂。

2、函数 fork_process

代码位于 src/backend/postmaster/fork_process.c, 没有什么很复杂的逻辑:

#ifndef WIN32...pid_tfork_process(void){...result = fork();if (result == 0){

注意:这里有preprocessor,上边这段代码是 #ifndef WIN32 控制,也就是只在 *nix下有效。

3、Windows下的后端进程创建

编译Windows版的方法,可以自行阅读,它不一样的地方之一是启用预处理符 EXEC_BACKEND。这个开关在*nix一样有效,有兴趣可以自己试试启用它编译Linux版,个人感觉进程fork效率一定要低很多。

函数 backend_forkexec 中:

av[ac++] = "postgres";av[ac++] = "--forkbackend";

这里增加两个参数,一个是程序启动的文件名,一个是参数forkbackend,指定这是要启动一个fork后端的进程,启动过程中会有一些影响:

if (strcmp(argv[1], "--forkbackend") == 0 ||...    PGSharedMemoryReAttach();


4、参数传递

fork()不需要考虑变量传递的问题,EXEC_BACKEND 时保存到临时文件里:

paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,...param = MapViewOfFile(paramHandle, ......if (!save_backend_variables(param, port, pi.hProcess, pi.dwProcessId))...

这部分代码在 EXEC_BACKEND  函数实现 internal_forkexec 里,可以结合Windows文档去理解。


5、为新进程准备共享内存

if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess))

以后有机会写共享内存时再写,感觉尤其是Windows下挺有必要。

6、进程创建

在调用 save_backend_variables 之前:

  if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,             NULL, NULL, &si, &pi)){

这里 cmdLine安装路径\postgres.exe --forkbackend nnn,最后一个参数是参数处理句柄,第一个参数的计算前几天写过。

从微软文档看,并没有说新创建的进程与postmaster之间是父子关系:

Creates a new process and its primary thread. The new process runs in the security context of the calling process.

7、后端进程启动不一样的处理分支

Windows下调用 SubPostmasterMain

...#ifdef EXEC_BACKEND  if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)    SubPostmasterMain(argc, argv);  /* does not return */#endif...

此函数位于:src/backend/postmaster/postmaster.c

SubPostmasterMain(int argc, char *argv[])

8、参数读入

在Windows下,读取由 CreateFileMapping 创建的文件映射句柄:

#ifdef _WIN64  paramHandle = (HANDLE) _atoi64(id);#else  paramHandle = (HANDLE) atol(id);#endif  paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);


9、共享内存ReAttach

if (strcmp(argv[1], "--forkbackend") == 0 ||    strcmp(argv[1], "--forkavlauncher") == 0 ||    strcmp(argv[1], "--forkavworker") == 0 ||    strcmp(argv[1], "--forkboot") == 0 ||    strncmp(argv[1], "--forkbgworker=", 15) == 0)    PGSharedMemoryReAttach();

大致就是这些。
如果觉得公众号阅读代码不便,可以访问我的博客:https://my.oschina.net/quanzl/,或者使用电脑版微信。

欢迎关注

dfa0aa172ab83b83c3f19601434a371a.png

欢迎关注飞象数据

7e2ee4e1d5980ef2a239bbd5d46ea8d5.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值