pthread realizes multithreaded program under Linux (one thread controls the pause, resume and termination of two threads)

Keywords: Unix

1, Functional requirements

Three threads are used. Thread 1 is used to listen to user input and as listener of other two threads. The main content of thread 2 is to output "hello 2" string every other period of time. Thread 3 is used to output "hello 3" string every other period of time. Change the state of thread 1 and thread 2 according to the input data

To realize the creation, pause, recovery, termination and other operations of threads, and control them by inputting numbers. Specifically, after creation, they are suspended by default,

  • 1 resume thread 2, 2 pause thread 2, 3 terminate thread 2,
  • 5 resume thread 3, 6 pause thread 3, 7 terminate thread 3.

Among them, resume and pause can be repeated alternately.

2, Main function

pthread_create: create thread function in UNIX Environment

pthread_join: used to wait for the end of a thread.

 

The first two and the last two are used in pairs, which can be used alternately according to the needs of the scene

pthread_mutex_lock: mutually exclusive lock

pthread_mutex_unlock: mutex unlock

pthread_cond_signal: conditional wake up

pthread_cond_wait: conditional wait

3, Running screenshot

 

Why can't threads be suspended / suspended immediately? When inputting 2 or 6, threads 2 and 3 will have an output?

Answer: the input read in thread 1 and the pause / suspend operation executed in threads 2 and 3 cannot respond immediately

4, Main code

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>

/*
1 Resume thread 2, 2 pause thread 2, 3 terminate thread 2,
5 Resume thread 3, 6 pause thread 3, 7 terminate thread 3.
*/
static int input=0;   //Receive keyboard input
static pthread_t id1,id2,id3;//Threads 1, 2, 3
//Conditional variable and mutex initialization
pthread_cond_t c2  = PTHREAD_COND_INITIALIZER;
pthread_cond_t c3  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t m3 = PTHREAD_MUTEX_INITIALIZER;

//Thread 1
void FunOne(void) {
	//First start blocking thread 2, 3
	pthread_mutex_lock(&m2);
	pthread_mutex_lock(&m3);
	while(1) {
		scanf("%d", &input);
		switch(input) {
			case 1:
				//Resume thread 2;
				printf("Resume thread 2...\n");
				pthread_cond_signal(&c2);//Send a signal to wake up the waiting process
				pthread_mutex_unlock(&m2);//It will be called multiple times in the while loop
				break;
			case 3:
				//Terminate thread 2;
				pthread_cancel(id2);
				printf("Terminate thread 2...\n");
				break;
			case 5:
				//Resume thread 3;
				printf("Resume thread 3...\n");
				pthread_cond_signal(&c3);
				pthread_mutex_unlock(&m3);
				break;
			case 7:
				//Terminate thread 3;
				pthread_cancel(id3);
				printf("Terminate thread 3...\n");
				break;
		}
	}
}
//Thread 2
void FunTwo(void) {
	pthread_mutex_lock(&m2);
	while(1) {
		if(input==2) {
			printf("Suspend thread 2...\n");
			pthread_cond_wait(&c2, &m2);//The thread executing this function will be suspended
		} else {
			sleep(2);
			printf("hello 2! \n");
		}
	}
	pthread_mutex_unlock(&m2);
}
//Thread 3
void FunThree(void) {
	pthread_mutex_lock(&m3);
	while(1) {
		if(input==6) {
			printf("Suspend thread 3...\n");
			pthread_cond_wait(&c3, &m3);//The thread executing this function will be suspended
		} else {
			sleep(2);
			printf("hello 3! \n");
		}
	}
	pthread_mutex_unlock(&m3);
}

int main(int argc,char* argv[]) {

	int res1 = pthread_create (&id1, NULL, (void *) FunOne, NULL);
	sleep(1);//Let thread 1 seize the cpu first, and let threads 2 and 3 block through the mutex
	int res2 = pthread_create (&id2, NULL, (void *) FunTwo, NULL);
	int res3 = pthread_create (&id3, NULL, (void *) FunThree, NULL);
	if(res1!=0||res2!=0||res3!=0) {
		printf("create error!\n");
		return -1;
	}
	/**
	*Block the process to execute the specified thread
	*/
	pthread_join(id1,NULL);
	pthread_join(id2,NULL);
	pthread_join(id3,NULL);

	pthread_mutex_destroy(&m2);//Destroy mutex
	pthread_mutex_destroy(&m3);//Destroy mutex

	return 0;
}

5, Summary

Thread 2 and 3 are suspended for the first time because thread 1 locks the mutex first, while threads 2 and 3 are suspended because they are waiting for the condition signal

Here, we can't only use a mutex and a condition variable. When a thread mutex unlocks or sends a condition signal, it will wake up other waiting threads and can't control the execution of a certain thread. You can try to control by setting some global variables.

Code may have other problems, for reference only!

 

Posted by iamali on Thu, 04 Jun 2020 19:53:07 -0700