简体   繁体   中英

why `fork()` does't show cow in my test program?

#include <fcntl.h>
#include <semaphore.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/stat.h> /* For mode constants */
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <thread>

using namespace std;



const char* shm_path = "conn_close_test";

char buf[] = "666";

int main() {
  sem_t* sem_child;
  sem_t* sem_parent;

  // int flag = O_CREAT | O_EXCL | O_RDWR;
  int flag = O_CREAT | O_RDWR;
  // create share memory object
  int fd = shm_open(shm_path, flag, S_IRUSR | S_IWUSR);
  if (fd == -1) {
    std::cout << "create failed  for reason: " << strerror(errno) << std::endl;
    return -1;
  }

 int page_size = 4096;

  if (ftruncate(fd, page_size  * 2) == -1) {
    std::cout << "ftruncate failed : " << strerror(errno) << std::endl;
    return -1;
  }

  // create semphore
  sem_child = (sem_t*)mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE,
                           MAP_SHARED, fd, 0);
  if ((__int64_t)(sem_child) == -1) {
    std::cout << "mmap sem child  failed for reason:" << strerror(errno)
              << std::endl;
  }

  sem_parent = (sem_t*)mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE,
                            MAP_SHARED, fd, page_size);
  if ((__int64_t)(sem_parent) == -1) {
    std::cout << "mmap sem parent failed for reason:" << strerror(errno)
              << std::endl;
  }

  int ret = sem_init(sem_child, 1, 0);
  if (ret == -1) {
    std::cout << "sem_child sem_init failed for: " << strerror(errno)
              << std::endl;
    return -1;
  }
  ret = sem_init(sem_parent, 1, 0);
  if (ret == -1) {
    std::cout << "sem_parent sem_init failed for: " << strerror(errno)
              << std::endl;
    return -1;
  }

  // fork
  pid_t pid = fork();
  if (pid == 0) {
    // child process read buf first  then post a semophore to wakeup parent process
    std::cout << "children first read\n";
    std::cout << "buf: " << buf << std::endl;
    std::cout << "sem_child post to wake up parent process" << std::endl;
    sem_post(sem_child);

    std::cout << "child process waiting for  sem_parent" << std::endl;
    sem_wait(sem_parent);
    std::cout << "children second read\n";
    std::cout << "buf: " << buf << std::endl;
  } else if(pid > 0 ){

    std::cout << "parent process waiting for sem_child\n";
    sem_wait(sem_child);
    std::cout << "parent  first read\n";
    std::cout << "buf: " << buf << std::endl;

    buf[0] = buf[1] = buf[2] = '7';
    std::cout<<"modify buf "<<std::endl;
    std::cout << "buf: " << buf << std::endl;

    std::cout<<"sem_parent post to wake up child process"<<std::endl;
    sem_post(sem_parent);
  }
  return 0;
}

compile it and run

chenbh@ubuntu:~/projects/conn_close_test$ g++ sem_test.cpp -lrt -lpthread -O0 -g 
chenbh@ubuntu:~/projects/conn_close_test$ ./a.out 
parent process waiting for sem_child
children first read
buf: 666
sem_child post to wake up parent process
child process waiting for  sem_parent
parent  first read
buf: 666
modify buf 
buf: 777
sem_parent post to wake up child process
children second read
buf: 666

here is my program, I make a buffer in parent process, then fork a child process to read the buffer and the parent process start to wait for a semaphore posted by child process, parent process will change the content of buffer after receive semaphore and notify child process to read it again, but my program shows child process read the old content of buffer, according to fork() 's cow , child process doesn't change the content of buffer then it should read the newest content from it, isn't it?

thanks for comments, I am now understanding copy-on-write ;

when parent process execute system call as fork or exec , prosess's memory pages will be set to read-only, these memory pages will be copied to parent/child's process space while parent/child process tries to write these memory pages.

I was wrong to think cow is child process copy memory pages from parent process firstly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM