I am trying to simulate a race condition (is this a correct term?) in order to fix it with semaphores afterward.
I have a master.c
process:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
for(int i = 0; i < 100; ++i)
{
if (fork() == 0)
{
char str[12];
sprintf(str, "%d", i%10);
execl("./slave", "slave", str, (char *)0);
}
}
return 0;
}
And a slave.c
process which prints into a file:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
FILE *p_file;
p_file = fopen("out.txt", "a");
for (int i = 0; i < 100; ++i)
{
usleep(100000); // I tried using this but it changes nothing
fprintf(p_file, "%s", argv[1]);
}
fprintf(p_file, "\n");
return 0;
}
The output file out.txt
looks like this:
https://pastebin.com/nU6YsRsp
The order is "random", but no data is not corrupted for some reason. Why is that?
Because stdio
uses buffered output by default when writing to a file, and everything you're printing in each process fits into a single buffer. The buffer doesn't get flushed until the process exits, and then it's written as a single write()
call, which is small enough to be written atomically to the file.
Call fflush(p_file);
after each fprintf()
and you'll get more mixed up results. Or call setvbuf()
to disable buffering.