1.线程概述
进程是系统中程序执行和资源分配的基本单位。每个进程都拥有自己的数据段、代码段和堆栈段,这就造成了进程在进行切换等操作时都需要有比较复杂的上下文切换等动作。为了进一步减少处理机的空转时间,支持多处理器以及减少上下文切换开销,进程在演化中出现了另一个概念——线程。它是进程内独立的一条运行路线,处理器调度的最小单元,也可以称为轻量级进程。线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享。因此,线程的上下文切换的开销比创建进程小很多。
2.线程机制的分类
线程按照其调度者可以分为用户级线程和核心级线程两种。
3.线程的函数格式
【1】pthread_create()函数语法要点
所需头文件 #include <pthread.h>
函数原型 int pthread_create ((pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg))
函数传入值 thread:线程标识符
attr:线程属性设置(其具体设置参见9.2.3小节),通常取为NULL
start_routine:线程函数的起始地址,是一个以指向void的指针作为参数 和返回值的函数指针
arg:传递给start_routine的参数
函数返回值 成功:0
出错:返回错误码
【2】pthread_exit()函数语法要点
所需头文件 #include <pthread.h>
函数原型 void pthread_exit(void *retval)
函数传入值 retval:线程结束时的返回值,可由其他函数如pthread_join()来获取
【3】pthread_join()函数语法要点
所需头文件 #include <pthread.h>
函数原型 int pthread_join ((pthread_t th, void **thread_return))
函数传入值 th:等待线程的标识符
thread_return:用户定义的指针,用来存储被等待线程结束时的返回值( 不为NULL时)
函数返回值 成功:0
出错:返回错误码
【4】pthread_cancel()函数语法要点
所需头文件 #include <pthread.h>
函数原型 int pthread_cancel((pthread_t th)
函数传入值 th:要取消的线程的标识符
函数返回值 成功:0
出错:返回错误码
4.线程实例"thread.c"
以下实例中创建了3个线程,为了更好地描述线程之间的并行执行,让3个线程重用同一个执行函数。每个线程都有5次循环(可以看成5个小任务),每次循环之间会随机等待1~10s的时间,意义在于模拟每个任务的到达时间是随机的,并没有任何特定规律。
#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));
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]; //定义一个线程数组3
int no=0,res;
void *thrd_ret; //定义一个指向任意类型的空指针
srand(time(NULL)); //??
for(no=0;no<THREAD_NUMBER;no++) //创建一个多线程3
{
res = pthread_create(&thread[no],NULL,thrd_func,(void *)no);
//int pthread_create ((pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg))
//thread 线程标识符,attr线程属性设置一般为NULL,start_routine:线程函数的起始地址,是一个以指向void的指针作为参数和返回值的函数指针,rg传递start_routine的参数;成功返回0;
if(res!=0)
{
printf("create thread %d failed\n",no);
exit(res);
}
}
printf("create threads success\n watiing for threads to finsih \n");
for(no=0;no<THREAD_NUMBER;no++)
{
res=pthread_join(thread[no],&thrd_ret);//int pthread_join ((pthread_t th, void **thread_return))th:等待线程的标识符thread_return:用户定义的指针,用来存储被等待线程结束时的返回值(不>为NULL时)成功:0
if(!res)
{
printf("thread %d joined \n",no);
}
else
{
printf("thread %d join failed \n",no);
}
}
return 0;
}
编译运行:gcc -o thread thread.c ./thread
运行结果:
Create treads success
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 1 delay = 6
Thread 2: job 1 delay = 8
Thread 0: job 1 delay = 8
Thread 2: job 2 delay = 3
Thread 0: job 2 delay = 3
Thread 2: job 3 delay = 3
Thread 2: job 4 delay = 1
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