| Lecture 5: Orthogonality, Processes, and Races |
| CS111: Operating Systems |
| Scribes: Yuhuang Chen, Jianan Li and Chuchu Ding |
1. Recap of Previous Lectures
Different operating systems deploy different schemes when it comes to kernel abstraction
Examples:
2. Processes
|
![]() |
Code example: program that prints out the time of the day
//Program that prints out the time of the day
bool printdate() {
pid_t p = fork();
switch(p) {
case -1:
error();
case 0: {
static char const date[] = "/bin/date";
execvp("/bin/date", (char const *){date,0});
error(); //execvp doesn't return if succeed
}
default: {
int status;
if (waitpid(p,&status,0) != p)
error();
}
}
//WIFEXITED: if child terminated normally, returns ture
//WEXITSTATUS(status) prints out the real exit status
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
}
//Program that prints out the time of the day to a file
bool printdate(char const *outfile) {
pid_t p = fork();
switch(p) {
case -1:
error();
case 0: {
static char const date[] = "/bin/date";
int fd = open(outfile, O_WRONLY);
if (fd < 0)
error();
if (dup2(fd,1) < 0)
error();
if (fd != 1)
close(fd);
execvp("/bin/date", (char const *){date,0});
error(); //execvp doesn't return if succeed
}
default: {
int status;
if (waitpid(p,&status,0) != p)
error();
}
}
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
}
Usual pattern for executing a program:
if(fork() == 0) {
//Housekeeping;
execvp(...);
}
Another school of thought, which is simpler and does all jobs in one system call:
int posix_spawnvp( pid_t * restrict pid, char const *restrict file, posix_spawn_file_actions_t const * restrict file_acts, posix_spawn_attr_t const * restrict attrp, char * const * restrict argv, char * const * restrict envp );
posix_spawnvp doesn't copy all that memory(imagine you copied 8GB memory only to do an execvp), so it is very efficient and fast and cheap.
3. Orthogonality
Comparison of Linux’s files:
4. IPC (Interprocess Communication)
Buffers are located in kernel memory
5. Race Conditions
Code example: creating a temporary file that stores sorted data.
// create_temp_file returns the new file descriptor, or -1 if an error occurred
//Proposal:
int create_temp_file(void) {
return open("/tmp/sort.tmp",O_RDWR|O_CREAT|O_TRUNC,0600);
}
//Problem: when two sort programs are running at the same time, one will trash the other's temp file!
//Fix:
int create_temp_file(void) {
char name[1000];
sprintf(name, "/tmp/sort.%d", getpid());
return open(name, O_RDWR|O_CREAT|O_TRUNC,0600);
}
//name[1000] is an char array big enough to hold our temp file's name
//sprintf() puts "/temp/sort." and our process ID into name[1000]. (e.g. "/temp/sort.30149", where 30149 is our process ID) Thus, no two sort programs running at the same time can trash each other's temp files because each process has a unique process ID!
//Problem: what if someone else has already created the same file and you don't have the access to open it?
//Fix:
int create_temp_file(void) {
char name[1000];
int fd;
while (1) {
sprintf(name, "/tmp/sort.%d", random());
if((fd = open(name, O_RDWR|O_CREAT|O_TRUNC|O_EXCL,0600)) > 0)
return fd;
}
}
//now we have a loop, and a random name generator. O_EXCl flag ensures that when the file with the same name already exists, open() should fail.
//Simplified version:
int create_temp_file(void) {
for(;;) {
sprintf(name, some_random_string());
if(open(name, O_RDONLY|O_CREAT|O_TRUNC|O_EXCL))
return open(name, O_WRONLY, 0600);
}
}
//Problem: now race condition arises! What if two sort call open() on the same file at the same time?