Linux同步拾遗

原创 2011年01月10日 22:01:00

一般情况下,线程在主题函数退出的时候会自动终止,但同时也可以因为接收到另一个线程发来的终止请求而强制终止。
线程取消的方法是向目标线程发cancel信号,但如何处理cancel信号则由目标线程自己决定,或者忽略,或者立即终止,或者继续运行到cancelation-point(取消点),由不同cancelation状态决定。
线程收到cancel信号的却醒处理是继续运行到取消点,也就是设置一个CANCELED状态,线程继续运行,只有运行到cancelation-point的时候才会退出。
根据POSIX标准,pthread_join,pthread_testcancel,pthread_cond_wait,pthread_cond_timedwait,sem_wait,sigwait以及read,write等会引起足赛的系统带哦用都是取消点,而其他pthread函数都不会引起cancelation动作。但是pthread_cancel的手册声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是Cancelation-point;但Cancel信号会使线程从足赛的系统调用中退出,并置EINTR错误码,因此可以在需要作为Cancelation-point的系统调用前后调用pthread_testcancel(),从而达到POSIX标准所要求的目标。
如果线程处于无限循环中,且循环体内没有执行至取消点的必然路径,则线程无法由外部其他线程的取消请求而终止,因此在这样的循环体的必经路径上应该加入pthread_testcancel()调用。
与线程取消有关的pthread函数:
int pthread_cancel(pthread_t thread);
发送终止信号给线程,如果成功则返回0,否则非0。
int pthread_setcancelstate(int state, int *oldstate)
设置本线程对cancel信号的反应。
int pthread_setcanceltype(int type, int* oldtype)
设置本县成取消动作的执行实际,type由两种趣旨:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYNCHRONOUS,仅当cancel状态为enable时,分表表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出)。
void pthread_testcancel()
检查本县成是否处于cancel状态,如果是,则进行取消动作。

pthread_join用来等待一个线程的结束。函数原型为:
extern int pthread_join __P(pthread_t __th, void** __thread_return);
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它用来存储线程返回值。这个函数是一个足赛函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被回收。在Linux中默认情况下在一个线程被创建后必须使用此函数对创建的线程进行资源回收,但是可以设置ThreadAttributes来设置当一个线程结束时直接回收此线程占用的系统资源。

Linux还有为线程在取消点退出而准备的pthread_cleanup_push,pthread_cleanup_pop。

pthread_cond_wait()函数一进入wait状态就会自动release mutex.
pthread_cond_wait()函数一旦wait成功获得cond条件的时候就会自动lock mutex.

一个经典的cond_wait/broadcast使用:
pthread_mutex_lock(&mut);
while (x <= y) {
  pthread_cond_wait(&cond, &mut);
}
/* modifies on x and y */
pthread_mutex_unlock(&mut);

pthread_mutex_lock(&mut);
if (x > y) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mut);
表面上signal只唤醒第一个线程,broadcast唤醒全部线程,但是pthread_cond_signal在多处理器上可能同时唤醒多个线程。
至于为什么被唤醒之后还要再次进行条件判断(即为什么要使用while循环来判断条件),是因为可能有惊群现象。

自旋锁是为实现保护共享资源而提出的一种锁机制,与互斥锁不同,它会先循环等待锁是否已经释放,一般来说,自旋锁有一个参数限定最多持续尝试次数,超出后,自动放弃当前time slice,等下一次机会。自选所比较适用于锁保持着保持锁比较短的情况。

相关文章推荐

计算机底层知识拾遗(七)页缓存数据同步和页回收机制

这篇说说Linux的页缓存数据同步和页回收机制。数据同步和页回收是两个独立的概念,数据同步处理的是内存/缓存的数据和后备设备的数据一致问题,页回收处理的是在内存空间不足时如何回收已分配的物理内存页,来...
  • ITer_ZC
  • ITer_ZC
  • 2015年03月12日 13:27
  • 2846

C++拾遗--多线程:主线程与子线程的同步

C++拾遗--多线程:主线程与子线程的同步 前言 在多线程编程时,有时是需要要求主线程与子线程同步的。 正文 下面的一个例子,演示了主线程与子线程之间的同步问题。 程序描述: 在主线程中,有一...

Linux拾遗

/dev/null 2>&1 0 标准输入 1 标准输出 2 标准出错输出 >/dev/null 是将执行结果屏蔽 2>&1 是将标准输出和标准出错一起重定向到一个文件中 ----------...
  • cyk968
  • cyk968
  • 2011年11月24日 13:19
  • 135

Linux 驱动模型初探4——汇总和拾遗

Linux 驱动模型初探4——汇总和拾遗 1,直接上code #include #include #include #include #include #include #...
  • koffuxu
  • koffuxu
  • 2014年12月13日 13:54
  • 1037

鸟哥LInux学习拾遗(1)

1、显示时间、日期   date  cal # date 2016年 03月 17日 星期四 09:01:53 CST # cal       三月 2016 日 一 二 三 四 五 六 ...

Linux进程与线程及其他知识点拾遗

0x00进程与线程的区别    进程和线程都是由父进程创建出来了,区别在于是否共享页表和页目录表。    进程是通过系统调用fork来创建的。使用全新的页表和页目录表,实行copy_on_write策...
  • jltxgcy
  • jltxgcy
  • 2017年07月08日 17:06
  • 402

Linux(Ubuntu)命令拾遗

Linux下的命令记录,持续记载Ubuntu更换镜像源:vim /etc/apt/sources.list修改里面内容,例如换成阿里源:deb http://mirrors.aliyun.com/ub...
  • picway
  • picway
  • 2017年05月11日 14:57
  • 283

Linux 问题解决拾遗

1, Ubuntu更换镜像源: vim /etc/apt/sources.list 修改里面内容,例如换成阿里源: deb http://mirrors.aliyun.com/ubunt...
  • picway
  • picway
  • 2017年08月09日 19:56
  • 148
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux同步拾遗
举报原因:
原因补充:

(最多只允许输入30个字)