kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
阅读:2380回复:14

很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误

楼主#
更多 发布于:2004-05-15 21:02
今天浏览了一个叫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 修改 ]
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
1C#
发布于:2004-05-15 21:55
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
所以概念决定设计!

可惜偶脑袋里的概念还太少了。 -------------------- 当个好的屠夫一直是我的梦想
当个好的屠夫一直是我的梦想
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
2C#
发布于:2004-05-15 22:06
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
怎么会有机会玩上 posix 这个东东~ -------------------- 当个好的屠夫一直是我的梦想
当个好的屠夫一直是我的梦想
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
3C#
发布于:2004-05-15 22:28
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
怎么会有机会玩上 posix 这个东东~

--------------------
当个好的屠夫一直是我的梦想


玩LINUX就是在玩posix系统...

posix可是GNUer的教主RMS提议的啊..


天才,他妈的一群天才!
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
4C#
发布于:2004-05-15 23:35
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
智力思考题:
Windows的WaitForMultiObject是必需的吗?
:)
九歌
普通会员
普通会员
  • 铜币0枚
  • 威望0点
  • 贡献值0点
5C#
发布于:2004-05-16 14:49
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
请教kmwang

双至强cpu开启超线程后

是不是可以同时运行两组完全相同的posix线程?

名称,互斥量,内存地址。。。。都相同!
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
6C#
发布于:2004-05-19 00:25
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
智力思考题:
Windows的WaitForMultiObject是必需的吗?
:)

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 );
}
当个好的屠夫一直是我的梦想
kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
7C#
发布于:2004-05-22 22:31
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
线程没有名称,只有线程ID(LInux和进程ID共用),且不同线程都有自己的栈,两个线程不可能内存完全相同,低级的线程库不分组.线程的调度是由操作系统进行调度的,和线程库无关,先把线程的基本概念搞清楚再说吧,你的每个问题都是问题:0
dabou:
对吗?:)先查查WaitForMutiObject的函数说明.我上面的说的太绝对了.
九歌
普通会员
普通会员
  • 铜币0枚
  • 威望0点
  • 贡献值0点
8C#
发布于:2004-05-23 11:54
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
可能我那天说的太不严紧

至强cpu的超线程功能可以硬拷贝单cpu或对称双cpu的所有线程

实现一个虚拟cpu,但我不清楚硬拷贝的线程是否完全相同,如果

完全相同,操作系统如何区分呢?
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
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 就通过. 这种比上一种简单, 模拟出上一种就没必要模拟这一种了.
所以 模拟第一种情况,关键还得保持原子操作(或是互斥的操作?)

乎乎, 得先上伙班, 下班再继续 :)
当个好的屠夫一直是我的梦想
kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
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线程的同步,不是吗,但谁作到了?
笑了
著名写手
著名写手
  • 铜币3枚
  • 威望0点
  • 贡献值0点
11C#
发布于:2004-05-29 22:52
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
请教kmwang

双至强cpu开启超线程后

是不是可以同时运行两组完全相同的posix线程?

名称,互斥量,内存地址。。。。都相同!


俺给你回答~~~

        所谓超线程技术就是利用特殊的硬件指令,把多线程处理器内部的两个逻辑内核模拟成两个物理芯片,从而使单个处理器就能“享用”线程级的并行计算的处理器技术。多线程技术可以在支持多线程的操作系统和软件上,有效的增强处理器在多任务、多线程处理上的处理能力。
        超线程技术可以使操作系统或者应用软件的多个线程,同时运行于一个超线程处理器上,其内部的两个逻辑处理器共享一组处理器执行单元,并行完成加、乘、负载等操作。这样做可以使得处理器的处理能力提高30%,因为在同一时间里,应用程序可以充分使用芯片的各个运算单元。
  对于单线程芯片来说,虽然也可以每秒钟处理成千上万条指令,但是在某一时刻,其只能够对一条指令(单个线程)进行处理,结果必然使处理器内部的其它处理单元闲置。而“超线程”技术则可以使处理器在某一时刻,同步并行处理更多指令和数据(多个线程)。可以这样说,超线程是一种可以将CPU内部暂时闲置处理资源充分“调动”起来的技术。另外,为了避免CPU处理资源冲突,负责处理第二个线程的那个逻辑处理器,其使用的是仅是运行第一个线程时被暂时闲置的处理单元。例如:当一个逻辑处理器在执行浮点运算(使用处理器的浮点运算单元)时,另一个逻辑处理器可以执行加法运算(使用处理器的整数运算单元)。这样做,无疑大大提高了处理器内部处理单元的利用率和相应的数据、指令处吞吐能力。
--------------------
累了,就将心靠岸 错了,就想到后悔 苦了,才懂得满足 伤了,才明白坚强 醉了,才知道难忘 笑了,才体会美丽
笑了
著名写手
著名写手
  • 铜币3枚
  • 威望0点
  • 贡献值0点
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 笑了 修改 ]
累了,就将心靠岸 错了,就想到后悔 苦了,才懂得满足 伤了,才明白坚强 醉了,才知道难忘 笑了,才体会美丽
九歌
普通会员
普通会员
  • 铜币0枚
  • 威望0点
  • 贡献值0点
13C#
发布于:2004-05-30 12:12
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
引用: 她妈妈的,微软这个贱货,在2000上取消了超线程支持,我得去核对一下,要是真的在WIN2K AD SERVER上也取消了,那就骂死微软,干他奶奶的,欺人太甚了,逼着人家买win2003,花了几十万买的服务器,结果都他妈的是非超线程的,亏大了~~~~


那就改用linux!!! [ 2004-05-30 12:12:54 九歌 修改 ]
猪八戒
写手
写手
  • 铜币1枚
  • 威望0点
  • 贡献值0点
14C#
发布于:2004-06-05 19:22
Re:很多人对Windows和posix pthread线程的区别很不清楚,竟然一个自由基础软件包也犯了严重错误
还有就是超线程需要和CPU,主板芯片,操作系统有关,我查了一下:
(1)需要CPU支持
        目前正式支持超线程技术的CPU有Pentium4 3.06GHz 、2.40C、2.60C、2.80C 、3.0GHz、3.2GHz以及Prescott处理器,还有部分型..


win2000 adv上面支持
我回帖还是有质量的
游客

返回顶部