You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

When using the fork() command, file descriptors are copied between the two new processes and will cause concurrent operations to occur on the same file. This can cause data to be read or written in a non-deterministic order to or from a file.

Non-Compliant Code Example

char c;
int pid;

int fd = open(filename,O_RDWR,0);
if (fd == -1) {
  /* Handle error */
}
read(fd,&c,1);
printf("root process:%c\n",c);

pid = fork();

if(pid == 0){/*child*/
      read(fd,&c,1);
      printf("child:%c\n",c);
}else{ /*parent*/
      read(fd,&c,1);
      printf("parent:%c\n",c);
}

If the file accessed has contents "abc", the output of this program could be either
root process:aparent: bchild: c

or

root process: achild: bparent: c

This code's output cannot reliably be determined, and therefore should not be used.  Instead, file descriptors should not be passed through a fork() call and should be closed beforehand to prevent this possible error.

Complaint code example:

char c;

int pid;


int fd = open(filename,O_RDWR,0);
if (fd == -1) {
  /* Handle error */
}
read(fd,&c,1);
printf("root process:%c\n",c);

close(fd);

pid = fork();

if(pid == 0){/*child*/
      fd = open(filename,O_RDONLY,0);
      read(fd,&c,1);
      read(fd,&c,1);
      printf("child:%c\n",c)
;  }else{ /*parent*/
      fd = open(filename,O_RDWR,0);
      read(fd,&c,1);
      read(fd,&c,1);
      printf("parent:%c\n",c);
}

The output of this code is :
root process:a
child:b
parent:b

Because file descriptors access files in a sequential manner, the order in which the parent and child run can affect the order of access to the file, and because file descriptors are shared across multiple processes, this allows multiple processes to read/write from a file concurrently in a semi-random order. 

  • No labels