UC3M

Telematic/Audiovisual Syst./Communication Syst. Engineering

Systems Architecture

September 2017 - January 2018

11.5.3.  Multithread reader-writer

Work Plan

The following piece of code is characterized by implementing a problem of reader-writer type: the (thread) reader reads data from the keyboard and stores them in a position. This position is read later when the (thread) writer writes to a memory location. The problem needs both threads are blocked; the writer must wait for the memory location is free, not underfoot; and the second thread needs to have something to print. This is the solution of the problem:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* compile with gcc -pthread *.c -o ./prod_consumer
 */
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0

char shared_array[204];
pthread_mutex_t lock= PTHREAD_MUTEX_INITIALIZER;
int string_read=FALSE;
pthread_cond_t cond= PTHREAD_COND_INITIALIZER;;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;;

//Reader thread
void * read1()
{
        while(TRUE)
	{
		pthread_mutex_lock(&lock);
                while(string_read)
		{
		  pthread_cond_wait(&cond2,&lock);
		}
                printf("\n[TH1] Enter a string (100 characters): ");
                scanf("%100s",shared_array); //unsafe with more than 204 characters
                string_read=TRUE;
		pthread_cond_signal(&cond);
                pthread_mutex_unlock(&lock);
        }
}

//Writer thread
void * write1()
{
        while(TRUE)
	{
                pthread_mutex_lock(&lock);
                while(!string_read)
		{
                  pthread_cond_wait(&cond,&lock);
		}
                printf("\n[TH2]The string entered is: \"%s\"\n",shared_array);
                string_read=FALSE;
		pthread_cond_signal(&cond2);
                pthread_mutex_unlock(&lock);
        }
}
int main()
{
        int status;
        pthread_t tr;
	pthread_t tw;
        pthread_create(&tr,NULL,read1,NULL);
        pthread_create(&tw,NULL,write1,NULL);
        pthread_join(tr,NULL);
        pthread_join(tw,NULL);
        return 0;
} 

Some aspects of the problem:

  • The solution uses a global lock lock to protect all access to shared information.

  • It uses two variable conditions (cond, cond2) so that each thread can safely sleep with a wait operation.

  • A thread notifies another when it has completed about your condition corresponding variable.

Using the previous example, you are required to perform de following actions:

  1. Download the code, compile it, and run the resulting application.

  2. Modify the code to read the scanf without lock taken. Hint: Divide the protected section into two blocks after reading the variables.

  3. Modify the code to replace the blocking waits for another active (with a sleep of a second). Which of the two solutions is more elegant: the sleeps, or using condition variables?