Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Datacasting How To Stream Databases Over The Internet

Authors: Jessica Keyes

1st Edition

007034678X, 978-0070346789

More Books

Students also viewed these Databases questions