UNIX下编写多线程程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UNIX多线程编程技术
posix pthreads库提供了一系列的编写多线程程序的函数
1.创建和中止线程函数
3.管理线程时序函数
使用线程时序管理函数会复杂你的程序算法在你移植你在单处
理机上的多线程程序到多处理机环境时也可能会带来麻烦
每一个线程都可以访问到相同的全局变量和文件
pthread_create函数
当一个程序被exec开始执行时会创建一个线程
其他的线程使用pthread_create创建
线程ID的数据类型为pthread_t
(通常为 unsigned int )ËüµÄID通过tid指针返回
调度优先级以daemon方式运行等等
如果attr为一个空指针
通常情况下
当创建一个线程的时候线程在开
始执行时调用该函数
开始函数地址为func变量如果
开始函数需要多个参数把所有的参数作为结构的成员注意变量func和arg返回一个通
用类型的指针(void *)Ï̷߳µ
»ØÒ»¸öÖ¸Õë(指向任务类型)
Èç¹ûÖ´Ðгɹ¦失败时返回非0
ÕâЩº¯Êý³ö´íʱ·µ»Ø和一个正的errno值指明失败原因例如
因为超过了系统线程数的限制而失败
Pthread函数不使用errno变量失败返回一个正数的约定是考虑周到的
并且0是没有使用的
把线程与进程相对比的话
pthread_join相当于waitpid
int pthread_join( pthread_t tid, void **status );
Returns:0 if OK
非常不幸
1)
Èç¹ûstatus的指针为非NONE
当一个线程调用了pthread_join后直到pthread_join指定的线程中止后才继续执行如果你在程序中忘记了调用pthread_join³ÌÐòÔËÐÐʱ¿ÉÄÜ»áÒòΪ×ÊÔ´²»×ã¶ø³öÎÊÌâ
有时候你可能不关心一个线程的存在状态
这时候你可以用pthread_detach函数
pthread_self 函数
在一个进程中所有的线程都有一个ID来标识
在pthread_join函数中也使用了线程ID
#include
pthread_t pthread_self( void );
Returns: thread ID of calling thread.
pthread_self类似于UNIX进程的getpid
缺省状态下线程是可连接的它的线程ID和终止状态将一直保存到有另外一个线程调用pthread_joinµ±ËüÖÕֹʱ
²¢ÇÒÎÞ·¨µÈ´ýËüµÄÖÕÖ¹
×îºÃÈÃÆäΪ¿ÉÁ¬½ÓµÄ(joinable)
#include
int pthread_detach( pthread_t tid );
Returns: 0 if OK
此函数最常用的情况是使某线程本身不可连接
pthread_detach( pthread_self());
pthread_exit 函数
线程终止的一种方法是调用pthread_exit函数
#include
void pthread_exit( void *status);
如果线程不是detached
status指针一定不能指向线程的局部变量
另外还有两种情况会导致线程终止
既然开始函数必须返回一个void指针
(2)进程的main函数返回或任何一个线程调用exit时
pthread_mutex_lock函数
当线程要访问(读或写)共享数据的时候例
其他线程要使用此数据时就会被暂时挂起
需要注意的时一个线程不应该一直锁住共享数据
以便其他线程可以利用
当要读取一个共享数据时把共享数据拷贝到一个临时本地变量中去
当要写一个共享数据时然后调用phtread_mutex_lock加锁共享数据然后立即调用pthread_mutex_unlock解锁
调用此函数会导致一个线程等待指定的条件变量被signaled或 broadcasted
pthread_mutex_lock(&mutex);/* lock mutex*/
while (!predicate) {/* check predicate*/
pthread_cond_wait(&condvar,&mutex);/* go to sleep - recheck
pred on awakening*/
}
pthread_mutex_unlock(&mutex);/* unlock mutex*/
当predicate等于0时pthread_cond_wait将做下面的两件事
为了唤醒它
pthread_mutex_lock(&mutex);/* lock the mutex*/
predicate=1;/* set the predicate*/
pthread_cond_broadcast(&condvar);/* wake everyone up*/
pthread_mutex_unlock(&mutex);/* unlock the mutex*/
pthread_cond_broadcast函数将唤醒所以的在等待条件变量condvar的线程
1.条件变量
条件变量用来完成这个行为
可以用pthread_cond_signal函数
predicate这个变量来决定是否要调用pthead_cond_wait函数
使用这个变量的原因是
而它并不知道有多少线程进入了睡眠状态
一个后来的线程可能错过另一个线程已经发出的broadcast而进入睡眠状态
3.mutexÓÉÓÚ˯ÃßÏß³ÌÒª¶ÁÈ¡predicate
所以必须对predicate使用互斥机制
这是因为一次只会唤醒一个睡眠的线程
则其他的进程就不会被唤醒
为什么pthread_cond_wait需要知道mutex变量呢
pthread_mutex_lock(&mutex);/* lock mutex*/
while (!predicate) {/* check predicate*/
pthread_mutex_unlock(&mutex);/* unlock mutex*/
pthread_cond_wait(&condvar);/* go to sleep - recheck
pred on awakening*/
pthread_mutex_lock(&mutex);/* lock mutex*/
}
pthread_mutex_unlock(&mutex);/* unlock mutex*/
这段程序会产生很大的问题
这时被切换到另外一个线程
这就导致了broadcast先于上面现成的pthread_cond_wait 执行这个本来应该进入睡眠的线程却没有进入