Chinaunix

标题: 各路英雄,在下有理啦! [打印本页]

作者: romanempire    时间: 2003-01-17 14:56
标题: 各路英雄,在下有理啦!
我想请问,在Unix环境下,怎样才能模拟Windows下的WaitForMultipleObjects这个函数,本人是这样实现的:

DWORD WaitForMultipleObjects(
                                                         DWORD nCount,             // number of handles in array
                                                         HANDLE *lpHandles,             // object-handle array
                                                         BOOL fWaitAll,            // wait option
                                                         DWORD dwMilliseconds      // time-out interval
                            )
{
        int iVal;
        BOOL bFlag = TRUE;
        int i;
        DWORD BlockTime=0;
        struct sembuf m_ops[1];
    do
    {
                m_ops[0].sem_op = -1;/*取资源*/
                        m_ops[0].sem_flg = IPC_NOWAIT;
                //m_ops[0].sem_flg = 0;
                m_ops[0].sem_num = 0;
               
      for( i = 0; i < nCount; i++ )
     {
         iVal = semop( lpHandles, m_ops, 1 );
        if ( iVal == -1 &amp;&amp; errno != EAGAIN &amp;&amp; errno != EINTR)
        {
      printf( "WaitForMultipleObjects error:%s\n", strerror( errno ) );
            return WAIT_ABANDONED_0;
        }
                       
        if( iVal == 0 &amp;&amp; !fWaitAll ) /* iVal==0, signal */
        {
            return i;                /*For fWaitAll=FALSE:return Values */
        }

        if( iVal != 0 )
        bFlag = FALSE;
                       
     }//end for
               
                Sleep(50);

                if( dwMilliseconds == INFINITE )
                {
                        BlockTime = INFINITE;//Block Wait
                        Sleep(100);
                        //sleep(1);
                }
                else
                {
                        BlockTime += 50;
                }
                       
        } while ( bFlag == FALSE &amp;&amp; BlockTime <= dwMilliseconds );
       
        return ((bFlag == TRUE) ? i : WAIT_TIMEOUT);

}
  这样实现就会造成死锁,而且不能使CPU真正投入睡眠状态,请高手指点,怎么实现才好?多谢!
作者: 无双    时间: 2003-01-17 17:29
标题: 各路英雄,在下有理啦!
试试看用pthread_cond_timedwait
作者: channelV    时间: 2003-01-17 18:47
标题: 各路英雄,在下有理啦!
sysv 标准下用这样的
        sembuf ops;
        ops.sem_num = 0;
        ops.sem_op = -1;
        ops.sem_flg = 0;        //0, IPC_NOWAIT, SEM_UNDO
        if ( semop(gsem_key, &amp;ops, 1) == 0 )
                return WAIT_OBJECT_0;

posix标准下用这样的
        if (sem_wait(&amp;gd_semaphore) ==0)
                return WAIT_OBJECT_0;               

是我自己写的,看你在哪个平台下用了
作者: 无双    时间: 2003-01-17 18:55
标题: 各路英雄,在下有理啦!
目的是想用一个函数来得到多个信号量的事件
这没有MSDN
不知道这样理解对不对
作者: channelV    时间: 2003-01-17 19:04
标题: 各路英雄,在下有理啦!
呵呵,必须有内容
作者: romanempire    时间: 2003-01-17 21:49
标题: 各路英雄,在下有理啦!
原帖由 "无双" 发表:
目的是想用一个函数来得到多个信号量的事件
这没有MSDN
不知道这样理解对不对

斑竹高明,是这样的目的,在Windows下该函数就是等待多个事件,根据参数不同有两种情况,一:等所有的信号资源都得到啦,才成功返回
                                二:得到了其中的某个信号资源就立即返回成功。
这两种情况的前提是在等待信号的期间系统没有异常的情况是这样的。
可是在Unix下情况好像不能实现是不是?有没有其他方式?请斑竹指点!
  非常感谢!
作者: romanempire    时间: 2003-01-17 21:51
标题: 各路英雄,在下有理啦!
原帖由 "channelV" 发表:
sysv 标准下用这样的
        sembuf ops;
        ops.sem_num = 0;
        ops.sem_op = -1;
        ops.sem_flg = 0;        //0, IPC_NOWAIT, SEM_UNDO
        if ( semop(gsem_key, &amp;ops, 1) == 0 )
                return WAIT_OBJECT_0;

posix标准下?.........


但我使用的是sysv标准,我不想使用posix标准,因为他现在还不能很通用,所以我想使用sysv标准来实现,不知道有没有办法?请大侠指点迷津,非常感谢!
作者: romanempire    时间: 2003-01-17 21:56
标题: 各路英雄,在下有理啦!
另外,我还有,使用上面的函数,居然捕捉不到系统的中断信号,
但如果把ops.sem_flg = 0,就可以捕捉到系统的中断信号,有没有其他办法在非阻塞模式(即ops.sem_flg = IPC_NOWAIT)时,怎样捕捉系统的中断信号,先谢谢啦。
作者: channelV    时间: 2003-01-17 22:00
标题: 各路英雄,在下有理啦!
其实是一样的了,unix/linux据我所知好像还没有提供这样的函数,你可以自己来写一个函数,里面是一个循环
waitformultipleobject--
for(int i=0; i<##; i++)
{
     if(sem_wait() != wait_object_0)
          return false;
}
实现起来是很简单的,偶就是这么做的,你可以参考一下
对不对还要请无双来考评一下
作者: romanempire    时间: 2003-01-17 22:08
标题: 各路英雄,在下有理啦!
原帖由 "channelV" 发表:
其实是一样的了,unix/linux据我所知好像还没有提供这样的函数,你可以自己来写一个函数,里面是一个循环
waitformultipleobject--
for(int i=0; i<##; i++)
{
     if(sem_wait() != wait_object_0)
   ..........

循环在这里,但不能使函数真正的阻赛在那里,那还是在占用CPU资源,另外,他还不能响应系统的中断信号。但好像只能再m_ops[0].sem_flg = 0;时,才能响应系统的中断信号,还有没有其他方式?谢谢
作者: 无双    时间: 2003-01-17 22:13
标题: 各路英雄,在下有理啦!
原帖由 "channelV" 发表:
其实是一样的了,unix/linux据我所知好像还没有提供这样的函数,你可以自己来写一个函数,里面是一个循环
waitformultipleobject--
for(int i=0; i<##; i++)
{
     if(sem_wait() != wait_object_0)
   ..........


你用sem_wait
那么就会阻塞在那了
因为sem_wait是阻塞函数
所以不能实现这个功能
作者: 无双    时间: 2003-01-17 22:16
标题: 各路英雄,在下有理啦!
如果是想等待所有事件的话那么用channelV  
的代码好了
但是如果是想等待某个事件的话
要另想办法

你看select函数对信号有没有用吧
如果有用的话那么可以用select实现

不然还是改用条件变量通知好了(当然代码要修改)
作者: romanempire    时间: 2003-01-17 22:18
标题: 各路英雄,在下有理啦!
原帖由 "无双" 发表:


你用sem_wait
那么就会阻塞在那了
因为sem_wait是阻塞函数
所以不能实现这个功能


我现在可以这样做个试验,使用定时器,在时间范围内,我就用阻赛调用,
超时后,再循环检测下一个信号灯。谢谢两位。等我的消息吧。
作者: 无双    时间: 2003-01-17 22:21
标题: 各路英雄,在下有理啦!
如果不能实现的话并且是在一个进程内同步的话
那么可以用
pthread_cond_timedwait

sem_trywait(S V 信号下使用相同功能的函数)

当一个信号释放时发一个cond 事件

waitformultipleobject函数等待这个事件
检查所有信号的锁状态
作者: romanempire    时间: 2003-01-18 13:48
标题: 各路英雄,在下有理啦!
问题已经解决,
虽然不是很完美,
但问题基本上解决啦,
我是通过定时器发送系统信号,
然后在waitformultipleobject函数中捕捉并检查该信号,
这样不仅完成了函数的阻塞也实现了轮训各个信号灯。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2