Programming Exercise 320 required you to design a PID manage

Programming Exercise 3.20 required you to design a PID manager that allocated a unique process identifier to each process. Exercise 4.20 required you to modify your solution to Exercise 3.20 by writing a program that created a number of threads that requested and released process identifiers. Now modify your solution to Exercise 4.20 by ensuring that the data structure used to represent the availability of process identifiers is safe from race conditions. Use Pthreads mutex locks, described in Section 5.9.4.

Exercise 3.20

An operating system’s pid manager is responsible for managing process identifiers. When a process is first created, it is assigned a unique pid by the pid manager. The pid is returned to the pid manager when the process completes execution, and the manager may later reassign this pid. Process identifiers are discussed more fully in Section 3.3.1. What is most important here is to recognize that process identifiers must be unique; no two active processes can have the same pid.

Use the following constants to identify the range of possible pid values:

#define MIN PID 300

#define MAX PID 5000

You may use any data structure of your choice to represent the availability of process identifiers. One strategy is to adopt what Linux has done and use a bitmap in which a value of 0 at position i indicates that a process id of value i is available and a value of 1 indicates that the process id is currently in use.

Implement the following API for obtaining and releasing a pid:

• int allocate map(void)—Creates and initializes a data structure for representing pids; returns—1 if unsuccessful, 1 if successful

• int allocate pid(void)—Allocates and returns a pid; returns— 1 if unable to allocate a pid (all pids are in use)

• void release pid(int pid)—Releases a pid

This programming problem will be modified later on in Chpaters 4 and 5.

Exercise 4.20

Modify programming problem Exercise 3.20 from Chapter 3, which asks you to design a pid manager. This modification will consist of writing a multithreaded program that tests your solution to Exercise 3.20. You will create a number of threads—for example, 100—and each thread will request a pid, sleep for a random period of time, and then release the pid. (Sleeping for a random period of time approximates the typical pid usage in which a pid is assigned to a new process, the process executes and then terminates, and the pid is released on the process’s termination.) On UNIX and Linux systems, sleeping is accomplished through the sleep() function, which is passed an integer value representing the number of seconds to sleep. This problem will be modified in Chapter 5

Solution

#include <iostream>

#include <stdlib.h>

#include <iostream>

#include <stdlib.h>

#include <pthread.h>
#include <windows.h>
using namespace std;
#define MIN_PID 300
#define MAX_PID 5000
int threadVar = 0;
pthread_mutex_t mutex;
struct pid_tab
{
int pid;
bool bitmap;
}pidArr[4700];
int allocate_map(void) //allocates bitmap values to the data structure
{
int i,j;
for(i = MIN_PID, j =0; i <= MAX_PID; i++, j++)
{
pidArr[j].pid = i;
pidArr[j].bitmap = 0;
}
if(i == MAX_PID && j == 4700)
return 1;
else
return -1;
}
int allocate_pid(void) //allocates a pid to the new process
{
for(int i = MIN_PID, j =0; i <= MAX_PID; i++, j++)
{
if(pidArr[j].bitmap == 0)
{
pidArr[j].pid = i;
pidArr[j].bitmap = 1;
return i;
break;
}
}
return -1;
}
void release_pid(int pid) //releases pid
{
for(int i = 0; i <= 4700; i++)
{
if(pidArr[i].pid == pid)
{
pidArr[i].bitmap = 0;
}
}
}
/* below function executes such that every thread only increments the threadVar by 1. Hence the output is numbers from 1 to 100 printed corresponding to each thread\'s execution.
The thread increments the value of threadVar by 1 and exits. Then the next thread increments by 1 again and exits. Every execution consists of a lock and unlock. */
void * threadCall(void* voidA) //function called by the created thread
{
int ret = allocate_pid(); //allocates a pid
while (threadVar < 100)
{
pthread_mutex_lock(&mutex); //mutex lock occurs
if (threadVar >= 100)
{
pthread_mutex_unlock(&mutex);
break;
}
threadVar++; //threadVar increments at least once
Sleep(100);
cout<<\"\ \"<<threadVar;
//cout<<\"\ \"<<pidArr[threadVar].pid;
pthread_mutex_unlock(&mutex); //mutex now unlocked
}
Sleep(5);
release_pid(ret); //pid released
}
int main()
{
int i =0;
pthread_t thread[100];
cout<<\"\ 100 threads created. Every thread will print the value of variable \'threadVar\' and increment it by 1 with a delay of 100ms each process execution\";
Sleep(3000); //delay only so that the above can be read in output screen before execution of the rest of the code
for(i = 0; i < 100; i++)
{
pthread_mutex_init(&mutex, NULL);
pthread_create(&thread[i], NULL, threadCall, NULL);
threadCall(NULL);
}
for(i = 0; i < 100; i++)
{
pthread_join(thread[i], NULL);
pthread_mutex_destroy(&mutex);
}
return 0;
}
Programming Exercise 3.20 required you to design a PID manager that allocated a unique process identifier to each process. Exercise 4.20 required you to modify
Programming Exercise 3.20 required you to design a PID manager that allocated a unique process identifier to each process. Exercise 4.20 required you to modify
Programming Exercise 3.20 required you to design a PID manager that allocated a unique process identifier to each process. Exercise 4.20 required you to modify
Programming Exercise 3.20 required you to design a PID manager that allocated a unique process identifier to each process. Exercise 4.20 required you to modify

Get Help Now

Submit a Take Down Notice

Tutor
Tutor: Dr Jack
Most rated tutor on our site