Question
Use of lockf C library function for process synchronization The shared resource responsible for race condition in the twoupdate program is an external file, and
Use of lockf C library function for process synchronization
The shared resource responsible for race condition in the twoupdate program is an external file, and is not an arbitrary in-memory data structure. Hence, it is possible to use file and record locking mechanisms available in UNIX to ensure mutual exclusion of the respective critical sections of the two processes, and thereby eliminate the race condition. The required system call in UNIX is fcntl. It is simpler to use a C library function called lockf built on top of fcntl. Spool out the man page for this library function and study it. The function prototype is as follows:
int lockf(int fd, int action, long size);
Two valid actions, defined as symbolic constants in , of interest to us are:
F_LOCK | Lock a section of a file for exclusive use, if it is available; if the section is already locked, the process blocks until the lock can be established |
F_ULOCK | Unlock a previously locked section of a file |
The third parameter size indicates the number of contiguous bytes to lock or unlock from the current position in the file. A value of zero for size indicates the entire section from the present position to the end of the file. Thus, by using a separate lseek system call to position at the beginning of the file before invoking lockf, the entire file can be locked or unlocked.
Suitably modify process0.c and process1.c to use the lockf function. Specifically, modify the function prototypes and invocations for both lockfile and unlockfile to allow passing the file descriptor as a parameter. Then modify the lockfile and unlockfile functions. Each requires exactly two lines of code.
Create a script output with a listing of all modified source files -- twoupdate.c, process0.c and process1.c. Show the output of four or five runs of twoupdate for small values of count, say below 30, and three fairly large values as specified for Part 2 of the assignment.
Source code for twoupdate.c
#include
#include
#include
int main (int argc, char *argv[])
{
FILE *fp; int initial, final; int status;
/*Check for command line arguments*/
if (argc != 3) {
printf("usage: twoupdate filename count ");
return -1;
}
/*Determine initial value in file before update*/
/*Uses standard C library functions for input/output*/
fp = fopen(argv[1], "r");
fscanf(fp, "%d", &initial);
fclose(fp);
/*Launch the two processes*/
if (fork() == 0) {
execlp("process0", "process0", argv[1], argv[2], (char *) NULL);
}
if (fork() == 0) {
execlp("process1", "process1", argv[1], argv[2], (char *) NULL);
}
/*Wait for the two processes to terminate*/
wait(&status); wait(&status);
/*Determine final value in file after update*/
fp = fopen(argv[1], "r");
fscanf(fp, "%d", &final);
fclose(fp);
/*Print value in file before and after two-process update*/
printf(" ****Initial value in file %d ", initial);
printf("****Final value in file %d ", final);
return 0;
}
Source code for process0.c
#include
#include
#include
#include
#include
#include
#include
void waste_time(void);
#define MAXSIZE 80
int main(int argc, char *argv[])
{
/*Uses UNIX input/output system calls for file access */
/*for no reason other than educational value*/
/*function prototype for file access*/
void fileaccess (int fd, int count);
int fd, count;
/*Check for command line arguments*/
if (argc != 3) {
printf("usage: process0 filename count ");
return -1;
}
count = atoi(argv[2]);
/*Open file and update*/
fd = open(argv[1], O_RDWR, 0);
fileaccess(fd, count);
return 0;
}
/*Access the file with the given fd and increment*/
/*the only integer value in that file count times*/
void fileaccess(int fd, int count)
{
/*function prototypes for locking and unlocking file*/
void lockfile (void);
void unlockfile (void);
int i, k, value; pid_t pid;
char buff[MAXSIZE];
/*Initialize the seed for random number generator*/
srand(time(NULL));
pid = getpid();
for (i = 0; i < count; i++)
{
lockfile(); /*lock the file*/
/*Read value from file*/
lseek(fd, 0L, 0);
k = read(fd, buff, MAXSIZE); buff[k] = '\0';
sscanf(buff, "%d ", &value);
/*Increment value*/
value++;
/*Slow down*/
waste_time();
/*Write back into file*/
sprintf(buff, "%10d ", value);
lseek(fd, 0L, 0);
k = strlen(buff); write(fd, buff, k);
printf("pid = %d, new value = %d ", pid, value);
unlockfile(); /*unlock the file*/
}
}
void waste_time (void)
{
/*Slow down; waste time in loop*/
int randNum = rand() % 100000; int x;
for (x = 0; x < randNum; x++) {
}
}
void lockfile(void)
{
}
void unlockfile(void)
{
}
Compile the code process0.c and name the executable file process0. Make a copy of process0.c as process1.c. Edit the file and replace every occurrence of the string process0 in it by process1. Compile the code process1.c and name the executable file process1.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started