|
阅读:2380回复:14
很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
今天浏览了一个叫ptype的软件包,发现下列代码.
以下是头文件 #ifdef WIN32 class ptpublic trigger: public noncopyable { protected: HANDLE handle; // Event object public: trigger(bool autoreset, bool state); ~trigger() { CloseHandle(handle); } void wait() { WaitForSingleObject(handle, INFINITE); } void post() { SetEvent(handle); } void signal() { post(); } void reset() { ResetEvent(handle); } }; #else class ptpublic trigger: public noncopyable { protected: pthread_mutex_t mtx; pthread_cond_t cond; int state; bool autoreset; public: trigger(bool autoreset, bool state); ~trigger(); void wait(); void post(); void signal() { post(); } void reset(); }; #endif 以下是c++实现 #ifdef WIN32 trigger::trigger(bool autoreset, bool state) { handle = CreateEvent(0, !autoreset, state, 0); if (handle == 0) trig_fail(); } #else inline void trig_syscheck(int r) { if (r != 0) trig_fail(); } trigger::trigger(bool iautoreset, bool istate) : state(int(istate)), autoreset(iautoreset) { trig_syscheck(pthread_mutex_init(&mtx, 0)); trig_syscheck(pthread_cond_init(&cond, 0)); } trigger::~trigger() { pthread_cond_destroy(&cond); pthread_mutex_destroy(&mtx); } void trigger::wait() { pthread_mutex_lock(&mtx); while (state == 0) pthread_cond_wait(&cond, &mtx); if (autoreset) state = 0; pthread_mutex_unlock(&mtx); } void trigger::post() { pthread_mutex_lock(&mtx); state = 1; if (autoreset) pthread_cond_signal(&cond); else pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mtx); } void trigger::reset() { state = 0; } #endif 也就是对windows和posix pthread实现触发器,但是两个实现完全相同吗? 当然不,pthread中的mutex和condition是最基本的两个同步概念,和Windows的mutex(或critical section),event重要性相同,只要有这两个东西,同步问题都可以实现,但是把mutex和这里的用pthread_condition实现的trigger合用却不行,因为如果一个线程调先调用pthread_cond_signal,然后另一个线程用phtread_cond_wait等待则不会得到响应,所以pthread_cond_wait必需和一个mutex合用,pthread_cond_wait时,对mutex解锁,等待条件,得到后立即对mutex加锁,这个过程是原子性的.而windows的event不是,他是一个状态量,不会丢失,所以上面两个实现差别大了! 至于后果,死锁是不可避免的,即使只是写一个简单的生产者消费者问题! 所以概念决定设计! 有好的实现吗?c++ boost 1.31.0,就是代码难懂点,概念绝对清晰. [ 2004-05-15 21:05:05 kmwang 修改 ] |
|
|
1C#
发布于:2004-05-15 21:55
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
所以概念决定设计! 可惜偶脑袋里的概念还太少了。 -------------------- 当个好的屠夫一直是我的梦想 |
|
|
|
2C#
发布于:2004-05-15 22:06
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
怎么会有机会玩上 posix 这个东东~
--------------------
当个好的屠夫一直是我的梦想 |
|
|
|
3C#
发布于:2004-05-15 22:28
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
怎么会有机会玩上 posix 这个东东~ 玩LINUX就是在玩posix系统... posix可是GNUer的教主RMS提议的啊.. 天才,他妈的一群天才! |
|
|
|
4C#
发布于:2004-05-15 23:35
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
智力思考题:
Windows的WaitForMultiObject是必需的吗? :) |
|
|
5C#
发布于:2004-05-16 14:49
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
请教kmwang
双至强cpu开启超线程后 是不是可以同时运行两组完全相同的posix线程? 名称,互斥量,内存地址。。。。都相同! |
|
|
6C#
发布于:2004-05-19 00:25
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
智力思考题: hello, kmwang: 是不是可以模拟: void wait( HANDLE mutex ) { WaitForSingleObject( mutex, INFINITE ); } void signal( HANDLE mutex ) { ReleaseMutex( mutex ); } /* 所有 mutexs 都 signal 才能通过 */ void WaitForMultiObjects( int size, HANDLE* mutexs ) { int i; bool modif[size]; do { wait( smutex ); for ( i=0; i<size; i++ ) { modif = false; } for( i=0; i<size; i++ ) { dw = WaitForSingleObject( mutexs, 0 ); if ( dw == WAIT_OBJECT_0 ) modif = true; else break; } if ( i != size ) { for( i=0; i<size; i++ ) { if ( modif ) ReleaseMutex( mutexs ); } } signal( smutex ); }while ( i != size ); } |
|
|
|
7C#
发布于:2004-05-22 22:31
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
线程没有名称,只有线程ID(LInux和进程ID共用),且不同线程都有自己的栈,两个线程不可能内存完全相同,低级的线程库不分组.线程的调度是由操作系统进行调度的,和线程库无关,先把线程的基本概念搞清楚再说吧,你的每个问题都是问题:0
dabou: 对吗?:)先查查WaitForMutiObject的函数说明.我上面的说的太绝对了. |
|
|
8C#
发布于:2004-05-23 11:54
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
可能我那天说的太不严紧
至强cpu的超线程功能可以硬拷贝单cpu或对称双cpu的所有线程 实现一个虚拟cpu,但我不清楚硬拷贝的线程是否完全相同,如果 完全相同,操作系统如何区分呢? |
|
|
9C#
发布于:2004-05-26 10:14
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
线程没有名称,只有线程ID(LInux和进程ID共用),且不同线程都有自己的栈,两个线程不可能内存完全相同,低级的线程库不分组.线程的调度是由操作系统进行调度的,和线程库无关,先把线程的基本概念搞清楚再说吧,你的每个问.. hello, kwmang: 线程的基本概念我还清楚, 只是不懂 posix :) WaitForMultipleObjects 的申明如下: DWORD WaitForMultipleObjects( DWORD nCount, // number of handles in the handle array CONST HANDLE *lpHandles, // pointer to the object-handle array BOOL fWaitAll, // wait flag DWORD dwMilliseconds // time-out interval in milliseconds ); Remarks: The WaitForMultipleObjects function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the criteria to be met. When fWaitAll is TRUE, the function's wait operation is completed only when the states of all objects have been set to signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects are also set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled. Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When fWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected. 您的问题是是否可以不需要 waitformulitobjects, 那需要用别的方式来替代它 先看看 WaitforSingleObject, 如果抛开对线程的管理, 只是关心它的 wait 功能,即等待信号量并阻塞.我觉得它会是这样 参数 HANDLE hHandle 句柄这种东东要绕个弯才能得到它所指向的内容,而且我不知如何获得其中的context 我用全局变量代替它 即不再传递 HANDLE hMutex, 传递一个 heap_variable 模拟一个最简单的功能,假如 把 heap_mem 所指向的内容看为个mutex, 则 mutex = 0,代表有信号 DWORD WaitforSingleObject( U32* heap_mem ) // ( HANDLE hHandle ) { __asm { _label: lock bts dword [heap_mem], 0 ; cf = pMem[0], pMem[0] = 1 lock 保证了原子性 jc _label } } 不过 msdn 声称 The thread consumes very little processor time while waiting for the object state to become signaled. 咋做到 consumes very little processor time 的呢? DWORD ReleaseObject( U32* heap_mem ) // ( HANDLE hHandle ) { *heap_mem = 0; } 而 waitforMultiObjects 只是对多个互斥量进行判断 (这里只考虑简单的互斥) 如果参数 1. fWaitAll = TRUE 是, 即所有互斥量都有信号是才通过,并分配资源. 上面的程序就是模拟这种情况的. 2. fWaitAll = FALSE 是 any of 就通过. 这种比上一种简单, 模拟出上一种就没必要模拟这一种了. 所以 模拟第一种情况,关键还得保持原子操作(或是互斥的操作?) 乎乎, 得先上伙班, 下班再继续 :) |
|
|
|
10C#
发布于:2004-05-28 23:21
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
这几天太忙了,主要是毕设:(
to 九哥: 我没有看过超线程的技术文档,但是硬拷贝线程不是一般意义上的线程.只要有两个pc计数器就可以实现,但是栈一定是不同的(或者干脆不用栈),只能有互斥操作,没有调度,线程必需有一个join点.只是推测而已.超线程我不认为是主流技术,意义有限. to dabou: 当然是wait为false的情况,注意考虑的是多个Event的情况. 在Unix里面,mutex&condition为一组完整的同步原语,semaphore是令外一个.在windows里面,同样提供了两组,semaphore和critical section (或mutex)& event,对于event则必需有WaitForMutiObject,否则不完整,你能用SetEvent 和 WaitForSingleObject实现WaitForMutiObject(当然不能用调度线程的方法),但是用semaphore一定可以. 上面的ptypes的实现是不完整的,只有里面的semaphore是比较完整的,但是timed semaphore的实现是有可能饿死人的.mutex和condition可以实现semaphore,同样semaphore也可以实现mutex & condition(大约都需要200-300行代码).这个思考题的目的是思考什么样的原语是完备的. 为什么说Dijkstra牛,一个信号量全搞定:),这就是概念. 所以学了操作系统的信号量,应该能完全掌握posix线程的同步和windows线程的同步,不是吗,但谁作到了? |
|
|
11C#
发布于:2004-05-29 22:52
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
请教kmwang 俺给你回答~~~ 所谓超线程技术就是利用特殊的硬件指令,把多线程处理器内部的两个逻辑内核模拟成两个物理芯片,从而使单个处理器就能“享用”线程级的并行计算的处理器技术。多线程技术可以在支持多线程的操作系统和软件上,有效的增强处理器在多任务、多线程处理上的处理能力。 超线程技术可以使操作系统或者应用软件的多个线程,同时运行于一个超线程处理器上,其内部的两个逻辑处理器共享一组处理器执行单元,并行完成加、乘、负载等操作。这样做可以使得处理器的处理能力提高30%,因为在同一时间里,应用程序可以充分使用芯片的各个运算单元。 对于单线程芯片来说,虽然也可以每秒钟处理成千上万条指令,但是在某一时刻,其只能够对一条指令(单个线程)进行处理,结果必然使处理器内部的其它处理单元闲置。而“超线程”技术则可以使处理器在某一时刻,同步并行处理更多指令和数据(多个线程)。可以这样说,超线程是一种可以将CPU内部暂时闲置处理资源充分“调动”起来的技术。另外,为了避免CPU处理资源冲突,负责处理第二个线程的那个逻辑处理器,其使用的是仅是运行第一个线程时被暂时闲置的处理单元。例如:当一个逻辑处理器在执行浮点运算(使用处理器的浮点运算单元)时,另一个逻辑处理器可以执行加法运算(使用处理器的整数运算单元)。这样做,无疑大大提高了处理器内部处理单元的利用率和相应的数据、指令处吞吐能力。 -------------------- |
|
|
|
12C#
发布于:2004-05-29 22:57
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
还有就是超线程需要和CPU,主板芯片,操作系统有关,我查了一下:
(1)需要CPU支持 目前正式支持超线程技术的CPU有Pentium4 3.06GHz 、2.40C、2.60C、2.80C 、3.0GHz、3.2GHz以及Prescott处理器,还有部分型号的Xeon。 (2)需要主板芯片组支持 正式支持超线程技术的主板芯片组的主要型号包括Intel的875P,E7205,850E,865PE/G/P,845PE/GE/GV,845G(B-stepping),845E。875P,E7205,865PE/G/P,845PE/GE/GV芯片组均可正常支持超线程技术的使用,而早前的845E以及850E芯片组只要升级BIOS就可以解决支持的问题。SIS方面有SiS645DX(B版)、SiS648(B版)、SIS655、SIS658、SIS648FX。VIA方面有P4X400A、P4X600、P4X800。 (3)需要主板BIOS支持 主板厂商必须在BIOS中支持超线程才行。 (4)需要操作系统支持 目前微软的操作系统中只有Windows XP专业版及后续版本支持此功能,而在Windows2000上实现对超线程支持的计划已经取消了。 她妈妈的,微软这个贱货,在2000上取消了超线程支持,我得去核对一下,要是真的在WIN2K AD SERVER上也取消了,那就骂死微软,干他奶奶的,欺人太甚了,逼着人家买win2003,花了几十万买的服务器,结果都他妈的是非超线程的,亏大了~~~~ [ 2004-05-29 23:04:17 笑了 修改 ] |
|
|
|
13C#
发布于:2004-05-30 12:12
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
引用: 她妈妈的,微软这个贱货,在2000上取消了超线程支持,我得去核对一下,要是真的在WIN2K AD SERVER上也取消了,那就骂死微软,干他奶奶的,欺人太甚了,逼着人家买win2003,花了几十万买的服务器,结果都他妈的是非超线程的,亏大了~~~~
那就改用linux!!! [ 2004-05-30 12:12:54 九歌 修改 ] |
|
|
14C#
发布于:2004-06-05 19:22
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
还有就是超线程需要和CPU,主板芯片,操作系统有关,我查了一下: win2000 adv上面支持 |
|
|