Linux API multithreading: threads, mutexes, conditional variables

Thread characteristics

1.After the program runs, it is a process, and threads are parasitic on the process
2.Threads share process code segments and public data of processes
3.Processes have separate address spaces. Threads have their own stack and local variables, but threads do not have a separate address space
4.Threads save space and improve efficiency (more people work faster). Facilitate inter thread communication (multiple threads parasitic on the same process, threadATransform data, threadBCan know immediately
5.Based on the above: after a process crashes, it will not affect other processes. The thread is placed on the process. If a process dies, the whole thread dies

Thread API description

pthread_create--Create process
pthread_join--Thread waiting
pthread_exit--Thread exit

pthread_mutex_init--Traumatic lock
pthread_mutex_destroy--Lock elimination
pthread_mutex_lock--Lock
pthread_mutex_unlock--Unlock

pthread_cond_init--Create condition variable
pthread_cond_destroy--Delete condition variable
pthread_cond_wait--Wait for condition trigger
pthread_cond_signal--Trigger condition

1, pthread_create -- create a process

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

Function description - create process
pthread_t *thread -- thread name
const pthread_attr_t *attr -- thread attribute (NULL is the default)
void *(*start_routine) (void *) -- function pointer of thread running
void *arg -- start needs to be passed in to run the code_ Parameters of routine function (if there are multiple parameters, put them into a structure)
Return value - 0 is returned successfully. The error returns EAGAIN (restrict the creation of new threads) and EINVAL (illegal thread property value)

2. Examples
The following routine demonstrates 1

2, pthread_join -- thread waiting

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_join(pthread_t thread, void **retval);

Function description - wait for the thread created to finish running
pthread_t thread -- thread name
void **retval -- the return value of the thread (set to NULL if not interested)
Return value - 0 is returned successfully.

2. Examples
The following routine demonstrates 1

3, pthread_exit -- thread exit

1. Original function

Header file
#include <pthread.h>
Define function
void pthread_exit(void *retval);

Function description - the thread exits and returns retval to pthread_ Retval parameter of join
*void retval -- the value returned to the waiting function after the thread exits
Return value - none

2. Examples
Routine Demo 1

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

void *fun(void *arg)
{
	static int ret=22;
	printf("This is thr,arg=%d,self=%ld\n",*((int *)arg),(unsigned long)pthread_self());//Output incoming value and frontline ID number
	pthread_exit((void *)&ret);//When the thread exits, the ret parameter is returned to the waiting thread
}

int main()
{
	printf("The srlf=%ld\n",(unsigned long)pthread_self());//Output current thread ID number

	pthread_t thr;
	int ar=10;
	int ret;
	ret=pthread_create(&thr,NULL,fun,(void *)(&ar));//Create a thread named thr, function named fun, and function parameter ar
	if(ret!=0)
	{
		printf("error\n");
		exit(-1);
	}
	
	int *data=NULL;
	pthread_join(thr,(void **)&data);//Wait for the thread to exit. data is the return value of thread exit
	printf("retu succeed,data=%d\n",*data);

	return 0;
}

Operation results:
The srlf=140614023730944
This is thr,arg=10,self=140614015444736
retu succeed,data=22

4, pthread_mutex_init - create lock pthread_mutex_destroy - lock elimination

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *restrict_attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

Function description - create a lock and finally cancel the lock
pthread_mutex_t *mutex -- lock name
const pthread_mutexattr_t *restrict attr -- the default value is NULL
Return value - 0 is returned for success

2. Examples
Routine Demo 2

5, pthread_mutex_lock - pthread_mutex_unlock - Unlock

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

Function description - the thread that gets the lock can run. Other threads need to wait for this thread to unlock and then get the lock to run
pthread_mutex_t *mutex -- lock name
Return value - 0 returned successfully

2. Examples
Routine Demo 2

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

pthread_mutex_t mutex;

void *fun(void *arg)
{
	pthread_mutex_lock(&mutex);//Thread fun takes the lock first and can run
	static char *p="Hello";
	printf("This is thr1,arg=%d,self=%ld\n",*((int *)arg),(unsigned long)pthread_self());
	pthread_mutex_unlock(&mutex);//Unlock
	pthread_exit((void *)p);//Quit fun's thread
}

void *fun1(void *arg)
{
	pthread_mutex_lock(&mutex);//Wait for the thread fun to unlock and then take the lock
	static char *p=" World";
	printf("This is thr2,arg=%d,self=%ld\n",*((int *)arg),(unsigned long)pthread_self()); 
	pthread_mutex_unlock(&mutex);//Unlock
	pthread_exit((void *)p);//Thread exiting fun1
}

int main()
{
        printf("The srlf=%ld\n",(unsigned long)pthread_self());//Output current thread ID number

        pthread_t thr;
        pthread_t thr1;
        int ar=10;
        int ret;

		pthread_mutex_init(&mutex,NULL);	//Build lock

        ret=pthread_create(&thr,NULL,fun,(void *)(&ar));//Create a thread named thr, function named fun, and function parameter ar
        ret=pthread_create(&thr1,NULL,fun1,(void *)(&ar));//Create a thread named thr1, function named fun1, and function parameter ar

        char *data=NULL;
        pthread_join(thr,(void **)&data);//Wait for thr thread to exit. data is the return value of thread exit
        printf("retu succeed,data=%s",data);
        pthread_join(thr1,(void **)&data);//Wait for thr1 thread to exit. data is the return value of thread exit
        printf("%s\n",data);

		pthread_mutex_destroy(&mutex);		//Lock elimination

        return 0;
}

Operation result: Fun locks first, fun 1pthread_ mutex_ The lock function waits for fun to unlock before locking
The srlf=140285058922240
This is thr1,arg=10,self=140285050636032
This is thr2,arg=10,self=140285042243328
retu succeed,data=Hello World

6, pthread_cond_init -- create condition variable pthread_cond_destroy -- delete condition variable

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *restrict);
int pthread_cond_destroy(pthread_cond_t *cond);

Function description - create condition variables and delete them after use
pthread_cond_t *cond -- condition variable name
const pthread_condattr_t *restrict -- the default quantity is NULL
Return value - 0 returned successfully

2. Examples
Routine demo 3

7, pthread_cond_wait -- wait for the condition to trigger pthread_cond_signal -- trigger condition

1. Original function

Header file
#include <pthread.h>
Define function
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);

Function description - thread calls pthread_cond_wait function, the program will get stuck in this function, and a trigger condition is required
The program can jump out of pthread_cond_wait function
pthread_cond_t *cond -- condition variable name
pthread_mutex_t *mutex -- lock name
Return value - 0 returned successfully

2. Examples
Routine demo 3

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

int g_data = 0;
pthread_mutex_t mutex;//Define lock name
pthread_cond_t cond;//Define condition variable name

void *func1(void *arg)
{
        while(1){
                pthread_cond_wait(&cond,&mutex);//Wait for trigger
                
                printf("t1 run\n");
                
                printf("t1:%d\n",g_data);
                g_data = 0;
                sleep(1);
        }
}
void *func2(void *arg)
{
        while(1){
                printf("t2:%d\n",g_data);
                
                pthread_mutex_lock(&mutex);//Lock
                g_data++;
                if(g_data == 3){
                 	pthread_cond_signal(&cond);//Trigger condition variable
                }
                
                pthread_mutex_unlock(&mutex);//Unlock
                sleep(1);
        }
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;
        
        char *pret = NULL;
        
        pthread_mutex_init(&mutex,NULL);		//Create lock
        pthread_cond_init(&cond,NULL);			//Create condition variable
        
        ret = pthread_create(&t1,NULL,func1,(void *)&param);	//Establish process 1
        
        ret = pthread_create(&t2,NULL,func2,(void *)&param);	//Establish process 2
        
        pthread_join(t1,(void **)&pret);	//Wait for process 1 to exit
        pthread_join(t2,(void **)&pret);	//Wait for process 2 to exit
        
        pthread_mutex_destroy(&mutex);		//Lock elimination
        pthread_cond_destroy(&cond);		//Delete condition variable
        return 0;
}

Running result: func2 process will g_ When data is added to 3, the condition variable is triggered, and func1 waits until G is triggered_ Set the data value to 0

Stars ~ read

Tags: Linux C

Posted by dcomartin on Mon, 18 Apr 2022 17:59:22 +0930