linux线程控制函数_第1页
linux线程控制函数_第2页
linux线程控制函数_第3页
linux线程控制函数_第4页
linux线程控制函数_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux线程控制 1、Linux下线程概述 进程是系统中程序执行和资源分配的基 本单位。每个进程有自己的数据段、代码 段和堆栈段。 线程是在共享内存空间中并发执行的多 道执行路径,他们共享一个进程的资源。 因为线程和进程比起来很小,所以相对 来说,线程花费更少的CPU资源。 用户地址空间 线程一线程二 线程三 进 程 图1 进程与线程的关系 2、linux线程实现 在linux中,一般采用Pthread线程库实现 线程的访问与控制。 由POSIX( Portable Operating System Interface of Unix,可移植性操作系统接口) 提出,具有良好的可移植性。 2.

2、1 线程创建、退出与等待 创建线程使用pthread_create函数。创建线程实际上就是 确定调用该线程函数的入口点。在线程创建以后,就开始 运行相关的线程函数。 该函数运行完之后,该线程也就退出了,这是线程退 出一种方法。 线程退出时使用函数pthread_exit,是线程的主动行为。 注意进程退出时使用exit函数,线程中用pthread_exit替 代exit。 由于一个进程中的多个线程共享数据段,因此通常在线程 退出后,退出线程所占用的资源并不会随线程结束而释放。 所有需要pthread_join函数来等待线程结束 类似于wait系统调用。 创建进程 #include pthread

3、_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) thread:线程标识符 attr:线程属性设置 start_routine:线程函数起始地址 arg:传递给start_routine的参数 退出线程 #include pthread_exit( void *retval ) retval: pthread_exit调用者线程的返回值, 可由其他函数如pthread_join来检测获取。 等待线程 #include pthread_join( pthread_

4、t *th,void *thread_return ) th:等待线程的标识符 thread_return:用户定义指针,用来存储被 等待线程的返回值 线程实例一 #include #include #include #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 dela

5、y_time = 0; int count = 0; printf(Thread %d is startingn, 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 = %dn, thrd_num, count, delay_time); printf(Thread %d finishedn, thrd_num

6、); pthread_exit(NULL); int main(void) pthread_t threadTHREAD_NUMBER; int no = 0, res; void * thrd_ret; srand(time(NULL); for (no = 0; no THREAD_NUMBER; no+) /* 创建多线程*/ res = pthread_create( if (res != 0) printf(Create thread %d failedn, no); exit(res); printf(Create treads successn Waiting for threa

7、ds to finish.n); for (no = 0; no THREAD_NUMBER; no+) /* 等待线程结束*/ res = pthread_join(threadno, if (!res) printf(Thread %d joinedn, no); else printf(Thread %d join failedn, no); return 0; 多线程编译 gcc example1.c -lpthread -o example1 2.2 修改线程属性 在thread_creat函数中有设置线程属性参数 这些属性包括绑定属性、分离属性、堆栈 地址、堆栈大小、优先级 系统默

8、认属性为非绑定、非分离、缺省1M 的堆栈、与父进程同样级别的优先级 属性设置 通常调用pthread_attr_init函数进行初始化 设置绑定属性的函数为pthread_attr_setscope 设置分离属性的函数是 pthread_attr_setdetachstate 设置线程优先级的相关函数 pthread_attr_getschdparm(获取线程优先级) pthread_attr_setschedparam(设置线程优先级) 在设置完成属性后,调用pthread_creat函数创 建线程 2.3 mutex互斥锁线程控制 mutex是一种简单的加锁的方法来控制对共 享资源的访问。

9、 在同一时刻只能有一个线程掌握某个互斥 锁,拥有上锁状态的线程能够对共享资源 进行访问。 若其他线程希望上锁一个已经被上了互斥 锁的资源,则该线程挂起,直到上锁的线 程释放互斥锁为止。 互斥锁的操作 主要包括以下几个步骤: 互斥锁初始化:pthread_mutex_init 互斥锁上锁:pthread_mutex_lock 互斥锁判断上锁:pthread_mutex_trylock 互斥锁解锁:pthread_mutex_unlock 消除互斥锁:pthread_mutex_destroy 互斥锁分类 互斥锁可分为三种: 快速互斥锁 递归互斥锁 检错互斥锁 这三种锁的主要区别在于其他未占有互斥

10、锁的线程在希 望得到互斥锁时是否需要阻塞等待。 快速互斥锁是指调用线程会阻塞直到拥有互斥锁的线程释 放为止。 递归互斥锁能够成功返回并且增加调用线程在互斥上加锁 的次数。 检错互斥锁则为快速互斥锁的阻塞版本,他会立即返回并 得到一个错误。 互斥锁初始化 #include int pthread_mutex_init( pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr) Mutex:互斥锁 Mutexattr: PTHREAD_MUTEX_INITIALIZER:创建快速互斥锁 PTHREAD_RECURSIVE_MUTE

11、X_INITIALIZER_NP:创建 递归互斥锁 PTHREAD_REEORCHECK_MUTEX_INITIALIZER_NP:创 建检错互斥锁 互斥锁操作 #include int pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_trylock(pthread_mutex_t *mutex) int pthread_mutex_unlock(pthread_mutex_t *mutex) int pthread_mutex_destroy(pthread_mutex_t *mutex) Mutex:互斥锁 返回值:

12、成功0,错误-1。 2.4 信号量线程控制 信号量也就是操作系统中所用到的PV操作,它 广泛用于进程或线程间的互斥与同步。 PV操作是对整数计数器信号量sem的操作。一 次P操作使sem减一,一次V操作使sem加一。 用于互斥时,几个进程(或线程)往往只设置 一个信号量sem。 用于同步时,往往设置多个信号量,并安排不 同的值了来实现它们之间的顺序执行。 开始 初始化信号量 V操作V操作 线程二执行 线程一执行 P操作P操作 结束 图2 信号量互斥操作 开始 初始化信号量 V操作sem1V操作sem2 线程二执行 线程一执行 P操作sem1P操作sem2 结束 图3 信号量同步操作 Linux

13、实现了POSIX.1的无名信号量,用于线程 的同步与互斥。 信号量操作函数: sem_init:用于创建一个信号量,并初始化它。 sem_wait或sem_trywait: 相当于P操作,它们都能 使信号量减一,两者区别在于当信号量小于零时, sem_wait会阻塞,而sem_trywait则会立即返回。 sem_post:相当于V操作,它将信号量的值加一同时 发出信号唤醒等待的进程。 sem_getvalue:得到信号量的值。 sem_destroy:删除信号量。 创建信号量 所需头文件#include 函数原型int sem_init(sem_t *sem,int pshared,unsi

14、gned int value) 函数传入值 sem:信号量指针 pshared:决定信号量能否在几个进程间共享。由于目前 Linux还没有实现进程间共享信号量,所以这个值只能够取0, 就表示这个信号量是当前进程的局部信号量 value:信号量初始化值 函数返回值 成功:0 出错:1 其他信号量函数 所需头文件#include 函数原型 int sem_wait(sem_t *sem) int sem_trywait(sem_t *sem) int sem_post(sem_t *sem) int sem_getvalue(sem_t *sem) int sem_destroy(sem_t *s

15、em) 函数传入值sem:信号量指针 函数返回值 成功:0 出错:1 线程实例二 #include #include #include #include #define THREAD_NUMBER 3 /*线程数*/ #define REPEAT_NUMBER 3 /*每个线程中的小任务数*/ #define DELAY_TIME_LEVELS 10.0 /*小任务之间的最大时间间隔*/ sem_t semTHREAD_NUMBER; void *thrd_func(void *arg) int thrd_num = (int)arg; int delay_time = 0; int coun

16、t = 0; /* 进行P操作 */ sem_wait( printf(Thread %d is startingn, 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 = %dn, thrd_num, count, delay_time); printf(Thread %d finishedn, thrd_num); pthread_exit(NULL); int main(void) pthread_t threadTHREAD_NUMBER; int no = 0, res; void * t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论