--%>

program is prone to deadlock when multi-variable used

  Give a brief introduction about the operation of your program and show that you understand the idea behind threads and mutual exclusion variable. Why do we need to use mutual exclusion to control the access of the three global variables? What is the potential problem if more than one task will require locking more than one mutual exclusion variable in its operation?

Answer:  Using parallel thread programming enhancing the computational power of the Processor by dividing program into independent threads. Thread is nothing but set of codes which the Operating system executes with the compiler. It is different from the traditional execution of the codes, where codes are executed sequentially and thus consuming more steps to finish a task. Parallel programming gives flexibility to coder to run simultaneous program using the multi-cores of a computer reducing the number of execution significantly, thus providing wide scope to handle large set of data and tasks simultaneously. Example when executing a large program in POSIX environment the memory allotted to the program is divided in cores, where first a thread executes and passing the value to the another thread function in the program. Parallel flow of such programs shortens the time of execution greatly. Since each thread has its own processing space therefore communication between threads will need to be done through a common global variable. Since multiple threads can access the same global variable this can leads to race condition. We know that each thread in the program has its own space, therefore to avoid confusion between programs we need to assign global variables in the beginning of the program. But now they are assessable to every thread in the program thus causing racing between threads. So it is obvious that we would like to avoid such scenario to occur, so in order to overcome such situation we use mutual exclusion variable, which is like a lock to prevent other thread's attempt to interfere with the Global variables currently  used by the executing thread and thus the thread have to wait till the operation of the concerned thread is over, failing to do so will result into deadlock condition where the program fails to execute further.  A mutex variable allow us to perform the lock/unlock action so that the critical section of the code can be protected. The main problem is circular wait, which is one of the four necessary condition required for deadlock. Therefore when multiple mutex are involved the order of the mutex lock and unlock is very important.

 

2.       Explain which part of the program is prone to deadlock when multi-variable is used and what measure you took to ensure that deadlock is avoided in the final program. Highlight the relevant section of your source code where multi-variable is used to control the access of the global variables.

Answer: the conditional portion of the thread function which manipulates the global variables for a particular thread, absence of proper locking sequence would result in a deadlock. To avoid deadlock in the final program we used mutex functions in the conditional loops in a ordered sequence unlocking them in the same order, thus avoiding deadlocks.

 

Following part of the program shows the application of multi-variable is used to control the access of the global variables(high lighted in yellow color).

 

void* PrintFactoryThread(void *threadid)
{

int i,process_id;
struct thread_data_struct *j_pt;
j_pt=(struct thread_data_struct *)threadid;
process_id=j_pt->thread_id; //assign thread id to process

printf("Factory thread starting.\n");
while (1)
{
pthread_mutex_lock(&revenue_lock);
pthread_mutex_lock(&product_lock);
pthread_mutex_lock(&parts_lock);
// lock revenue variable and test for termination conditon

if (revenue>=max_revenue)
{
pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

break;
}
if ((product0))
{
product++;
parts--;
revenue--;
printf("Factory: manufacturing. | Parts=%d |Products=%d | Revenue=%d|\n",parts,product,revenue);
}



else
{
if (product>=max_products)
printf("Factory: stock overflow! | Parts=%d | Products=%d | Revenue=%d \n",parts,product,revenue);
else if (parts<1)
printf("Factory: no parts! | Parts=%d | Products=%d | Revenue=%d |\n",parts,product,revenue);
}

pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

// delay the thread according to factory_delay
Sleep(factory_delay*1000);
}

 

3.Demonstrate that your program (include the program output as part of the final report) can produce the correct output with the following parameters. For each case comment if the output agree with the given parameters.

 

RTS_assignment C code


#include "stdafx.h"

#include "pthread.h"
#include
#include
#include

pthread_mutex_t product_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t parts_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t revenue_lock = PTHREAD_MUTEX_INITIALIZER;


int factory_delay=1;
int retail_delay=3;
int warehouse_delay=2;
int max_revenue=6;
int max_products=3;
int parts=0;
int revenue=0;
int product=0;


struct thread_data_struct{
int thread_id;
} ;


void* PrintFactoryThread(void *threadid)
{

int i,process_id;
struct thread_data_struct *j_pt;
j_pt=(struct thread_data_struct *)threadid;
process_id=j_pt->thread_id; //assign thread id to process


printf("Factory thread starting.\n");
while (1)
{
pthread_mutex_lock(&revenue_lock);
pthread_mutex_lock(&product_lock);
pthread_mutex_lock(&parts_lock);
// lock revenue variable and test for termination conditon

if (revenue>=max_revenue)
{
pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

break;
}





if ((product0))
{
product++;
parts--;
revenue--;
printf("Factory: manufacturing. | Parts=%d |Products=%d | Revenue=%d|\n",parts,product,revenue);
}



else
{
if (product>=max_products)
printf("Factory: stock overflow! | Parts=%d | Products=%d | Revenue=%d |\n", parts, product,revenue);
else if (parts<1)
printf("Factory: no parts! | Parts=%d | Products=%d | Revenue=%d |\n", parts, product, revenue);
}

pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

// delay the thread according to factory_delay
Sleep(factory_delay*1000);
}


printf("Factory thread terminating.\n");



//thread termination
pthread_exit(NULL);
return 0;
}

void* PrintRetailThread(void *threadid)
{

int i,process_id;
struct thread_data_struct *j_pt;
j_pt=(struct thread_data_struct *)threadid;
process_id=j_pt->thread_id; //assign thread id to process

printf("Thread Retail starting.\n");
while (1)
{
pthread_mutex_lock(&revenue_lock);
pthread_mutex_lock(&product_lock);
pthread_mutex_lock(&parts_lock);
// lock revenue variable and test for termination conditon
if (revenue>=max_revenue)
{
pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

break;
}
if (product>0)
{
product--;
revenue+=3;
printf("Retail: sale! | Products=%d | Revenue=%d |\n", product, revenue);
}
else
{
printf("Retail: out of stock! | Products=%d | Revenue=%d |\n", product, revenue);
}

pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);

// delay the thread according to retail_delay
Sleep(retail_delay*1000);
}


printf("Retail thread terminating.\n");

pthread_exit(NULL);
return 0;
}

void* PrintWareHousethread(void *threadid)
{

int i,process_id;
struct thread_data_struct *j_pt;
j_pt=(struct thread_data_struct *)threadid;
process_id=j_pt->thread_id; //assign thread id to process


printf("Warehouse thread starting.\n");
while (1)
{
pthread_mutex_lock(&revenue_lock);
pthread_mutex_lock(&product_lock);
pthread_mutex_lock(&parts_lock);
// lock revenue variable and test for termination conditon
if (revenue>=max_revenue)
{

pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);
break;
}




if (parts<1)
{
parts+=2;
revenue--;
printf("Warehouse: supplying parts to warehouse.| Parts=%d | Revenue=%d\n", parts, revenue);
}

else
printf("Warehouse: no need to replenish parts | Parts=%d | Revenue=%d\n", parts, revenue);

pthread_mutex_unlock(&revenue_lock);
pthread_mutex_unlock(&product_lock);
pthread_mutex_unlock(&parts_lock);


Sleep(warehouse_delay*1000);

}


printf("Warehouse thread terminating.\n");



//thread termination
pthread_exit(NULL);
return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
pthread_t thread_Factory,thread_Retail,thread_WareHouse;

int rc;
// declear the array for the thread_data structure
struct thread_data_struct thread_data[3];

thread_data[0].thread_id=1; //assign thread id to thread structure


rc = pthread_create(&thread_Factory, NULL, PrintFactoryThread, (void *) &thread_data[0]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
printf("Thread Factory: created.\n");



thread_data[1].thread_id=2; //assign thread id to thread structure


rc = pthread_create(&thread_Retail, NULL, PrintRetailThread, (void *) &thread_data[1]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
printf("Thread Retail: created.\n");


thread_data[2].thread_id=3; //assign thread id to thread structure


rc = pthread_create(&thread_WareHouse, NULL, PrintWareHousethread, (void *) &thread_data[2]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
printf("Thread WareHouse: created.\n");

pthread_join(thread_Factory, NULL);
pthread_join(thread_Retail, NULL);
pthread_join(thread_WareHouse, NULL);
printf("Joining all threads.\n");


return 0;
}

Case a.  factory_delay=1,  retail_delay=2,  warehouse_delay=3,  max_product=2 and

max_revenue=4.

Case b.  factory_delay=2,  retail_delay=1,  warehouse_delay=3,  max_product=3 and

max_revenue=4.

Case c.  factory_delay=1,  retail_delay=3,  warehouse_delay=2,  max_product=3 and

max_revenue=6.

   Related Questions in Programming Languages

  • Q : Explain String String: It is an

    String: It is an instance of the String class. A string comprises of zero or more Unicode characters, and they are not mutable or immutable, once formed. The literal string is written between a pair of string delimiters ("), as:

    Q : Explain different types of variable iv

    The kind of value that a variable can own is known as data type. When we state a variable we require specifying the type of value it will own with the n

  • Q : What is Timeslice Timeslice : It is the

    Timeslice: It is the amount of running time assigned to a process or thread prior to the scheduler considers the other to be run. The process or thread will not be capable to employ its full allocation of time when it becomes blocked or preempted thro

  • Q : Explain Operator Explain Operator with

    Explain Operator with their types and examples?

  • Q : Define Passing by value Passing by

    Passing by value: In this process separate memory builds for formal arguments and when any modifications done on formal variables, it will not influence the real variables. Therefore actual variables are preserved in this situation.

  • Q : Define Micro-Controller Define

    Define Micro-Controller.

  • Q : Explain the relationship between XHTML

    Explain the relationship between XHTML and HTTP?

  • Q : Explain This This : It is a Java

    This: It is a Java reserved word with numerous different uses: A) Within a constructor, it might be employed as the first statement to call the other constructor in similar class. For illustration:

    Q : Recursive Matlab function Write a

    Write a recursive Matlab function TriUVRCol that solves a virtually upper triangular system of equations accessing the matrix by column. Write another recursive Matlab function LUPivRec that recursively computes the LU decomposition of a matrix using partial pivoting.

  • Q : Write a recursive implementation of

    Assignment 5 Selecting Array Elements Implement the following C++ code in assembly language, using the block-structured .IF and .WHILE directives. Assume that all variables are 32-bit signed integers: int array[] = {10,60,20,33,72,89,45,65,72,18}; int sample = 50; intArraySize = s