Basic thread programming
1. Introduction to threads
In order to further reduce the idle time of the processor, support multi-processors, and reduce the overhead of context switching, another concept appears in the process of evolution-thread. It is an independent running line within the process, the smallest unit of processor scheduling, and is also called a lightweight process. Because of the high efficiency and maneuverability of threads, they are widely used in embedded system development.
The resources shared by multiple threads in a process include: executable instructions, static data, file descriptors opened in the process, current working directory, user ID, and user group ID
. Resources private to each thread include: thread ID (TID) ), PC (program counter) and related registers, stack, error number, priority, execution status and attributes
2. Programming Instructions
In Linux, the general pthread thread library is a set of general thread libraries, proposed by POSIX, and has good portability. The pthread thread library provides the following basic operations:
- Create thread: determine the entry point to call the thread function, use the pthread_create() function
- Recycling thread: release the resources occupied by the thread after it exits, use the pthread_join() function
- End thread: exit thread is the active behavior of thread, use pthread_exit() function
- End another thread in a thread: use the pthread_cancel() function
3. Function introduction
pthread_create()
/*****pthread_create()函数*****/
函数原型:int pthread_create(pthread_t *thread,pthread_attr_t *attr,void *(*start_routine)(void*),void *arg)
传 入 值:thread 线程标识符
attr 线程属性设置(详见属性介绍章节),通常取为NULL
start_routine 线程函数的起始地址,是一个以指向void的指针作为参数和返回值的函数指针
arg 传递给 start_routine 的参数
返 回 值:成功:返回0;失败:返回错误码
pthread_join()
/*****pthread_join()函数*****/
函数原型:int pthread_join(pthread_t th,void **thread_return)
传 入 值:th 等待线程的标识符
thread_return 用户定义的指针,用来存储被等待线程结束时的返回值(不为NULL时)
返 回 值:成功:返回0;失败:返回错误码
pthread_exit()
/*****pthread_exit()函数*****/
函数原型:void pthread_exit(void *retval)
传 入 值:retval 线程结束时的返回值,可由其他函数如pthread_join()来获取
pthread_cancel()
/*****pthread_cancel()函数*****/
函数原型:int pthread_cancel(pthread_t th)
传 入 值:th 要取消的线程的标识符
返 回 值:成功:返回0;失败:返回错误码
4. Programming Examples
The following example creates 3 threads. In order to better describe the parallel execution between threads, let the 3 threads share an execution function. Each thread has 5 cycles, each cycle will randomly wait 1~10 seconds, the meaning is that the arrival time of each task is simulated, and there is no specific rule
/*****thread.c*****/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER 3 //线程数
#define REPEAT_NUMBER 5 //每个线程中的小任务数
#define DELAY_TIME_LEVELS 10.0 //小任务之间的最大时间间隔
void *thrd_func(void *arg){
int thrd_num = (int)arg;
int delay_time = 0;
int count = 0;
printf("Thread %d is starting\n",thrd_num);
for(count = 0;count < REPEAT_NUMBER;count++){
delay_time = (int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf("\tThread %d: job %d delay = %d\n",thrd_num,count,delay_time);
}
printf("Thread %d finished\n",thrd_num);
pthread_exit(NULL);
}
int main(){
pthread_t thread[THREAD_NUMBER];
int no = 0,res;
void * thrd_ret;
srand(time(NULL));
for(no = 0;no < THREAD_NUMBER;no++){
res = pthread_create(&thread[no],NULL,thrd_func,(void*)no);
if(res != 0){
printf("Create thread %d failed\n",no);
exit(res);
}
}
printf("Create thread sucess\nWaiting for threads to finish...");
for(no = 0;no < THREAD_NUMBER;no++){
res = pthread_join(thread[no],&thrd_ret);
if(!res)
printf("Thread %d joined\n",no);
else
printf("Thread %d join failed\n",no);
}
return 0;
}
The following is the running result. It can be seen that the running and end of each thread are disorderly, independent and parallel
linux@linux-virtual-machine:~/andy/proc$ ./thread
Create threads sucess
Waiting for threads to finish...
Thread 0 is starting
Thread 1 is starting
Thread 2 is starting
Thread 1: job 0 delay = 6
Thread 2: job 0 delay = 6
Thread 0: job 0 delay = 9
Thread 1: job 0 delay = 6
Thread 2: job 0 delay = 8
Thread 0: job 0 delay = 8
Thread 2 finished
Thread 1: job 2 delay = 10
Thread 1: job 3 delay = 4
Thread 1: job 4 delay = 1
Thread 1 finished
Thread 0: job 3 delay = 9
Thread 0: job 4 delay = 2
Thread 0 finished
Thread 0 joined
Thread 1 joined
Thread 2 joined