多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。
- 基于进程的多任务处理是程序的并发执行。
- 基于线程的多任务处理是同一程序的片段的并发执行。
1. POSIX
POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用,比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。
创建线程
1
2
3
4
// 函数原型
int pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg);pthread_create
创建一个新的线程,并让它可执行。返回值:成功创建为0;
参数:
th
:指向线程标识符的指针;attr
:用于设置线程属性,可以使用默认值NULL
;func
:线程运行函数起始地址,一旦线程被创建就会执行;arg
:运行函数的参数,它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。
终止线程
如果需要只终止某个线程而不终止整个进程,可以有三种方法:
- 从线程函数
return
。这种方法对主线程不适用,从main函数return相当于调用 exit 。 - 一个线程可以调用
pthread_cancel
终止同一进程中的另一个线程。 - 线程可以调用
pthread_exit
终止自己。
使用下面的程序,我们可以用它来终止一个 POSIX 线程:
1
2// 函数原型
void pthread_exit(void *res);res
是void *
类型,和线程函数返回值的用法一样,其它线程可以调用pthread_join
获得这个指针。1
int pthread_join(pthread_t t, void **res);
调用该函数的线程将挂起等待,直到id为
t
的线程终止。t
线程以不同的方法终止,通过pthread_join
得到的终止状态是不同的,总结如下:- 如果
t
线程通过return
返回,res
所指向的单元里存放的是t
线程函数的返回值。 - 如果
t
线程被别的线程调用pthread_cancel
异常终止掉,res
所指向的单元里存放的是常数PTHREAD_CANCELED
。 - 如果
t
线程是自己调用pthread_exit
终止的,res
所指向的单元存放的是传给pthread_exit
的参数。
- 从线程函数
创建与退出线程示例
向线程传递参数
向线程传递参数时,涉及数据类型转化,记得进行转化。
线程同步
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。
互斥锁(mutex)
通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。
互斥锁是通过锁的机制来实现线程间的同步问题。互斥锁的基本流程为:
定义,初始化一个互斥锁
1
2pthread_mutex_t mutex; //声明
int a = pthread_mutex_init(&counter_mutex, NULL); //初始化加锁:
pthread_mutex_lock()
函数或pthread_mutex_trylock()
函数对共享资源的操作
解锁:
pthread_mutex_unlock()
函数注销互斥锁:
pthread_mutex_destory()
函数
条件变量(condition Variable)
定义、初始化
1
2pthread_cond_t cond;
int res = pthread_cond_init(&cond, NULL);等待条件变量
1
int res = pthread_cond_wait(&cond, &mutex);
参数说明:cond 条件变量地址,mutex互斥锁地址,表示锁等待在条件变量上.
唤醒等待条件变量上的线程
1
2int pthread_cond_signal(pthread_cond_t *cond); //唤醒等待该条件变量上的某个线程
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒等待该条件变量上的所有线程销毁条件变量:
1
int pthread_cond_destroy(pthread_cond_t *cond);
信号量(Semaphore)
这里先不介绍….
未完待续