作者:CppExplore 网址:http://www.cppblog.com/CppExplore/
为了后面写的《网络模型(二)》,多写一篇关于线程的。线程使用涉及的主要数据结构以及应用框架可以参考http://www.cppblog.com/CppExplore/archive/2008/01/15/41175.html。本文的主要目的是给出linux下实用的线程消息队列实现。
一、linux上线程相关的操作有下面几种:
(1)pthread_t类型的创建、属性创建设置等。
这类具体可以:man pthread_creat; man pthread_attr_init;man pthread_detach;man pthread_join;等查看
(2)pthread_mutex_t类型的操作。
这类具体可以: man pthread_mutex_init可以看到所有相关的操作。
(3)pthread_cond_t类型的操作。同样:man pthread_cond_init。pthread_cond_t的wait和signal操作一定要和pthread_mutex_t的lock、unlock配合使用。类似于此:
(4)sem_t类型的操作。同样:man sem_init 这个系列一般是用不到的,太重量级了,也是最强大的一种。
二、linux2.6内核的线程库。2.6内核的默认安装的是redhat公司的NPTL(原生posix线程库),以前内核安装的是LinuxThreads库,两者的简单介绍可以看http://www.ibm.com/developerworks/cn/linux/l-threading.html。不过对于应用者,分析两者的区别和优劣也没什么大意义。这里特别提下NPTL的futex机制。借助该机制,pthread_mutex的性能大大提高,只要不进入竞争态,进程就不会陷入内核态。这点可以自己写示例程序,通过strace -c 跟踪进程的系统调用得以证实,另外还可以证实总是进入内核态的操作有pthread_cond_signal和sem_post。
三、实用的线程消息队列实现。下面设计一个具有线程消息队列的线程封装类。通过上面的分析,我们可以有如下结论:
(1)减少pthread_cond_signal和sem_post的调用,只在有必要的时候调用;
(2)尽量避免pthread_mutex进入竞争态。增大消息队列的大小,可以有效减少竞态条件的出现。
下面给出一个实用的线程消息队列的实现类,这个类也将是以后《网络模型》文章中用到的线程消息队列类,代码注释请看对私有属性的注释:
下面给出这个线程消息队列的一个使用举例:
评论
????????????????????????????????????/
互斥变量的竞争和队列长度有什么相关?
无论队列长短,凡是要操作队列的动作,都必须获取互斥锁啊。
比如,consumer线程都在工作,producer就要不断写队列最后把队列给写满了,这时候队列长点能够多缓冲数据。
条件变量的特点就是没有wait的情况下signal会被丢弃,比如consumer一直忙,producer的signal就会被丢弃的,但是没有关系,只有在队列空情况下producer才需要cond wait,有数据情况下根本不需要wait直接操作即可(mutex保证了互斥)。
信号量的每次操作都不会被丢弃,相对系统代价应该比cond高了一些的。 回复 更多评论