cp命令实现的一些惨案—父子进程共享资源问题
前述:计划是研究linux的ipc技术的,想来倒不如直接动手实现cp/scp命令,然后不断升级改进,最后把技术学了,顺便熟悉下常见的api接口
思路:
char buffer[64k]
char *fp = &buffer;
int rflag = 0;
int *rp = &rflag;
pid = fork()
if pid > 0 ; then
使用fread()从文件中读取内容到buffer中
设置rflag = 1
循环等待 rflag 被子进程设置为0
继续执行上述循环
else
循环检测*rp也就是rflag的内容是否为1
为1则 *fp写到目标文件中
设置*rp = 0
本来想就算写时拷贝,只要我有指针子进程就可以为所欲为了,结果没想到调试的时侯直接给我个锤子
实现:
#include <sys/types.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define READBLOCK 64*1024 int main(int argc, char *argv[]) { char buffer[READBLOCK]; const char *pb = buffer; int rflag = 0; int *lock = &rflag; pid_t pid = fork(); if(pid > 0) { while(1) { rflag = 1; printf("p &rflag = %x\n", &rflag); sleep(1); rflag = 3; printf("p &rflag = %x\n", &rflag); sleep(1); } } else if( pid == 0) { while(1) { printf("child pid , lock = %x, rflag=%d\n", lock, *lock); sleep(1); } } return 0; }
调试时父子进程打印rflag的地址都是一样的,但是内容却不一样,子进程为0,父进程为1,3。
子进程如下
(gdb) i locals sfp = <optimized out> dfp = <optimized out> r = <optimized out> buffer = '\000' <repeats 60296 times>... pb = 0x7ffc4a7105d0 "" rflag = 0 lock = 0x7ffc4a7105b8 pid = 0 (gdb) p rflag $2 = 0 (gdb) p &rflag $3 = (int *) 0x7ffc4a7105b8 (gdb) p *(int*) 0x7ffc4a7105b8 $4 = 0 (gdb) p *(int*)0x7ffc4a7105b8 $5 = 0
父进程如下:
gdb) i locals sfp = <optimized out> dfp = <optimized out> r = <optimized out> buffer = '\000' <repeats 60296 times>... pb = 0x7ffc4a7105d0 "" rflag = 0 lock = 0x7ffc4a7105b8 pid = 3435090 (gdb) p &rflags No symbol "rflags" in current context. (gdb) p &rflag $1 = (int *) 0x7ffc4a7105b8 (gdb) s 85 printf("p &rflag = %x\n", &rflag); (gdb) i locals sfp = <optimized out> dfp = <optimized out> r = <optimized out> buffer = '\000' <repeats 60296 times>... pb = 0x7ffc4a7105d0 "" rflag = 3 lock = 0x7ffc4a7105b8 pid = 3435090 (gdb) p &rflag $2 = (int *) 0x7ffc4a7105b8 (gdb) p *(int *) 0x7ffc4a7105b8 $3 = 3
总的来说,哪怕用指针保留内存块的地址,然后fork(),之后就算想用从未修改过内容的指针来瞒天过海访问父进程的内容,也不行,这应该是写时复制的真正含义
一干解千愁

浙公网安备 33010602011771号