--%>

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 : Are you sure that XHTML element name

    Are you sure that XHTML element name case sensitive? Answer: XHTML element names surely are case sensitive. Every element names should be written within lower case l

  • Q : Define Stream class Stream class : An

    Stream class: An input stream class is one which delivers data from its source (frequently the file system as a series of bytes. Likewise, an output stream class will write byte-level data. The stream classes must be contrasted with the operation of r

  • Q : What is Logical error Logical error :

    Logical error: It is an error in the logical of a class or method. Such an error may not lead to an instant runtime error, however could have a noteworthy impact on overall program exactness.

  • Q : Explain Magic number Magic number : It

    Magic number: It is a constant value with significance within a specific context. For example, the value 12 could mean numerous different things - the number of hrs you have worked today, the number of dollars you are payable by a friend, and so forth

  • Q : Define Interpretational inner class

    Interpretational inner class: It is an inner class whose role is to give a view or interpretation of data belongs to its enclosing class, however independent of the data's real representation.

  • Q : Explain the differences among SEI

    What in your advice are the most important fundamental differences among SEI SW-CMM and ISO 9000-3?

  • Q : Define Unbounded repetition Unbounded

    Unbounded repetition: The repetition where statements in a loop's body are executed an arbitrary number of times, according to the consequences of the statements in the loop's body. All of the loop control structures in the Java offer for unbounded re

  • Q : Attatching CSS to HTML documents

    Explain the different ways in order to attach the CSS to HTML Documents?

  • Q : What is pipe What is meant by the term

    What is meant by the term pipe?

  • Q : What is BLAST in program model checking

    What is BLAST in program model checking: The abbreviation is Berkeley Lazy Abstraction Software Verification Tool (BLAST) is a software model checker for C programs. The main goal of BLAST (BLAST website) is to be able to check that software satisfies