In: Computer Science
Programming Assignment #2, Processes
./time <command [args...]>
and will report the amount of elapsed time to run the specified command. This will involve using fork() and execvp() functions, as well as the gettimeofday() function to determine the elapsed time. It will also require the use of two different IPC mechanisms.
The general strategy is to fork a child process that will execute the specified command. However, before the child executes the command, it will record a timestamp of the current time (which we term “starting time”). The parent process will wait for the child process to terminate. Once the child terminates, the parent will record the current timestamp for the ending time. The difference between the starting and ending times represents the elapsed time to execute the command. The example output below reports the amount of time to run the command ls:
./time ls -l
total 156 |
25616 Feb |
4 |
15:59 a.out |
||
-rwxr-xr-x 1 thomas users |
|||||
-rw-r--r-- 1 thomas users |
252 Feb |
4 |
16:00 output.txt |
||
-rwxr-xr-x 1 |
thomas users |
86024 |
Feb |
2 |
20:58 project.exe |
-rwxr-xr-x 1 |
thomas users |
25616 |
Feb |
2 |
21:00 time |
-rw-r--r-- 1 |
thomas users |
5144 |
Feb |
2 |
20:58 time.c |
Elapsed time: 0.001448 seconds
As the parent and child are separate processes, they will need to arrange how the starting time will be shared between them. You will write one version of this program, representing a method of IPC.
2a) The first version, time_shm.c, will have the child process write the starting time to a region of shared memory before it calls execvp(). After the child process terminates, the parent will read the starting time from shared memory. The region of shared memory should be established before the child process is forked, allowing both the parent and child processes access to the region of shared memory.
You will use the gettimeofday() function to record the current timestamp. This function is passed a pointer to a struct timeval object, which contains two members: tv_sec and tv_usec. These represent the number of elapsed seconds and microseconds since January 1, 1970 (known as the UNIX EPOCH). The following code sample illustrates how this function can be used:
timeval_t end_time;
gettimeofday( &end_time, 0 );
timersub( &end_time, startTime, &elapsed_time );
// print elapsed time (microseconds right justified zero filled)
printf( "\nElapsed time: %d.%06d seconds\n", elapsed_time.tv_sec, elapsed_time.tv_usec );
Hint:
3. ./time ls -l | tee time_shm_output.txt is an example command to run your program while collecting your program’s output to a text file and seeing the output on the console.
---------------------------------------------------------------ANSWER-------------------------------------------------------------------------
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h> 17
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/wait.h>
#if
!defined( USING_PIPES )
#define
USING_SHARED_MEMORY // Shared memory will be the default
implementation
#define IPC_METHOD "SHARED MEMORY"
#else
#undef USING_SHARED _MEMORY
#Define IPC_METHOD "Anonymous Pipe"
#endif
int main( int argc, char **argv )
{
if( argc <= 1 )
{
fprintf( stderr, "usage: %s [args...]\n",
argv[0] );
}
return -1;
typedef struct timeval timeval_t;
#ifdef USING_SHARED_MEMORY
// Shared memory setup
// 1) create the shared memory region
char sharedMemoryName[] = "Command Timer";
int sharedMemoryFD = shm_open(
sharedMemoryName, O_CREAT | O_RDWR, 0666 );
// 2) configure the size of the shared memory
region
ftruncate( sharedMemoryFD, sizeof(timeval_t) );
// 3) memory map the shared memory region
timeval_t * sharedMemory = mmap( 0, sizeof(timeval_t),
PROT_READ | PROT_WRITE, MAP_SHARED, sharedMemoryFD, 0 );
#else // USING_PIPES
//pipe setup
enum {READ_END =0,WRITE _END};
int pipeFD[2];
pipe(pipeFD);
#endif
if( fork() == 0 )
{
#ifdef USING_SHARED_MEMORY
// Get and save the current time into shared
memory,
gettimeofday( sharedMemory, 0 );
#else
close (pipeFD[READ_END]);
timeval_t startTime;
gettimeofday(&startTime,0);
write(pipeFD[write_END],&startTime,sizeof(startTime));
close(pipeFD[WRITE_END]);
#endif
execvp( argv[1], argv + 1 );
else // parent process
wait( 0 ); 129
// get the end time
timeval_t end_time;
gettimeofday( &end_time, 0 );
// get the start time
timeval_t startTime;
#ifdef USING_SHARED_MEMORY
startTime = *sharedMemory;
// The child placed the start time in shared
memory
shm_unlink(sharedMemoryName);
#else // USING_PIPES
close(pipeFD[WRITE_END]);
read (pipeFD[READ_END], &startTime,sizeof(startTime));
close(pipeFD[READ_END]);
#endif
// calculate elapsed time
timeval_t elapsed_time;
timersub( &end_time, &startTime,
&elapsed_time );
// print microseconds right justified zero
filled
printf( "\nElapsed time: %d.%06d seconds\n",
elapsed_time.tv_sec, elapsed_time.tv_usec );
printf( "IPC Method: %s\nCommand: ",
IPC_METHOD);
char ** arg = argv + 1;
while( *arg ) printf("%s ", *arg++);
printf("\n");
}
return 0;
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------