VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2518|回复: 7

linux下如何实现 类似Windows的WaitForMultipleObjects函数的功能

[复制链接]

1

主题

4

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
发表于 2020-2-12 22:30:01 | 显示全部楼层 |阅读模式
代码如下:
HANDLE handles[2] = {m_quitEvent.GetHandle(), m_semaphore.GetHandle()};
                UInt32 uWait = WaitForMultipleObjects(2, handles, False, MAX_TIMEOUT);
                if(uWait - WAIT_OBJECT_0 == 0)
                {
                        //退出信号
                        break;
                }


Linux代码如何实现呢?
回复

使用道具 举报

1

主题

4

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-4-10 11:30:01 | 显示全部楼层
代码如下:
HANDLE handles[2] = {m_quitEvent.GetHandle(), m_semaphore.GetHandle()};
UInt32 uWait = WaitForMultipleObjects(2, handles, False, MAX_TIMEOUT);
if(uWait - WAIT_OBJECT_0 == 0)
{
        //退出信号
        break;
}


Linux代码如何实现呢?
回复

使用道具 举报

1

主题

8

帖子

8.00

积分

新手上路

Rank: 1

积分
8.00
发表于 2020-6-11 09:15:01 | 显示全部楼层
sig_wait可以不?
回复

使用道具 举报

1

主题

4

帖子

5.00

积分

新手上路

Rank: 1

积分
5.00
 楼主| 发表于 2020-7-27 09:45:01 | 显示全部楼层
while(True)
{
        //退出信号,等待1毫秒
        if(m_quitEvent.Wait(1))
                break;

        //有信号
        if(m_semaphore.TryLock(0))
                break;
}
我现在是用以上代码模拟实现的,基本上实现了与WaitForMultipleObjects类似的功能;

问下还有没更简捷的函数代替;
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-9-2 18:45:02 | 显示全部楼层
我在 Linux 下实现了 win32 de 线程同步机制,哈哈!!自我陶醉一下下
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-9-2 19:00:01 | 显示全部楼层
#ifndef _M_THREAD_BASEOBJ_DEF_H_
#define _M_THREAD_BASEOBJ_DEF_H_
#include <pthread.h>
#include <semaphore.h>
#include <sys/select.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

#include <Carbon/Carbon.h>
class MCritSec  
{
private:
        pthread_mutex_t m_mutex;
public:
        MCritSec()
        {
                pthread_mutex_init (&m_mutex,NULL);
        }
        virtual ~MCritSec()
        {
                pthread_mutex_destroy(&m_mutex);
        }
        void Lock()
        {
                pthread_mutex_lock(&m_mutex);
        }
        void Unlock()
        {
                pthread_mutex_unlock(&m_mutex);
        }
};

class MAutoLock
{
protected:
    MCritSec * m_pLock;

public:
    MAutoLock(MCritSec * plock)
    {
        m_pLock = plock;
        m_pLock->Lock();
    }

    ~MAutoLock()
        {
        m_pLock->Unlock();
    }
};


class IDAllocator
{
typedef struct _IDNode
{
        unsigned long ID;
        _IDNode* Next;
}Node;
public:
        IDAllocator();
        virtual ~IDAllocator();
        unsigned long GetID();
        long ReleaseID(unsigned long nID);
       
private:
        MCritSec m_Lock;
        Node* m_pHead;
        unsigned long   m_nNextID;
        int   m_nLength;
        unsigned long  CalNextID(unsigned long nPreID);
       
       
};


#define MHANDLE_SUCCESS( T ) ((long)T >=0 )

enum
{
        HANDLE_TYPE_BASE,
        HANDLE_TYPE_MUTEX,
        HANDLE_TYPE_THREAD,
        HANDLE_TYPE_SEMAPHORE,
        HANDLE_TYPE_EVENT
};

enum
{
        HANDLE_STATE_THREADCREATE_SUSPEND=-1,
        HANDLE_STATE_UNVALID=0,
        HANDLE_STATE_VALID=1
       
};


enum
{
        HANDLE_NOTIFYTYPE_SIGNAL,
        HANDLE_NOTIFYTYPE_UNSIGNAL,
        HANDLE_NOTIFYTYPE_UPDATA
};


class MHandleManager;





typedef struct _ManagerNode
{
        MHandleManager* pMng;
        _ManagerNode*   Next;
}ManagerNode;

class MHBase  
{
public:
        MHBase();
        virtual ~MHBase();
       
private:
static IDAllocator g_ObjIDAllocator;

protected:
        int                                m_HandleType;
        unsigned long        m_HandleID;
        unsigned long        m_HandleState;


        virtual long        DelHeadManager();
        virtual long    DelManager(MHandleManager* pManager);
        virtual long        AddManager(MHandleManager* pManager);
        virtual long        NotifyManager(int NotifyType)=0;
       
        ManagerNode*    m_pMngListHead;
        ManagerNode*    m_pMngListTail;

        MCritSec        m_MngListLock;
        MCritSec        m_OPLock;


friend class MHandleManager;

};



typedef MHBase*  MHANDLE;


class MEvent:public MHBase
{
public:
        MEvent(bool InitState,bool IsManaul);
        virtual ~MEvent();
        void Set();
        void Reset();
        void Pulse();
private:
        bool m_bManaulReset;
        MCritSec m_Lock;
protected:
        long NotifyManager(int NotifyType);
       
       
};




class MSemaphore:public MHBase
{
public:
        MSemaphore(long nInitCounts,long nMaxCounts);
        virtual ~MSemaphore();
        long Signal(long nCounts=1);
private:
        long m_nMaxSigCounts;
        MCritSec m_Lock;
protected:
        long NotifyManager(int NotifyType);
};



class MMutex:public MSemaphore
{
public:
        MMutex(bool bInitState);
        ~MMutex();
};

typedef void*(*THREADFUNCPTR)(void*);
MHANDLE CreateThread(const pthread_attr_t *pAttr, void *(*start_routine)(void *), void *pArg, bool IsCreateSuspend);

class MThread:public MHBase
{
typedef enum {CREATE_BYNEW,CREATE_BYFUNC}CREATE_TYPE;
public:
        MThread();
        virtual ~MThread();
       
        long                        InitUsrThread(const pthread_attr_t *pAttr,void *pArg,bool IsCreateSuspend);
       

        virtual long   Resume();
        virtual long   Suspend(){return 0;};
        int            GetState(){return m_HandleState;}

protected:
        CREATE_TYPE m_nCreateType;
       
        pthread_t                m_Thread;
        pthread_attr_t        m_ThreadAttribute;
        void*                        m_pArg;
        THREADFUNCPTR        m_pThrdFunc;
       
        MHANDLE   m_evntRun;
       
protected:
        static void*        ThreadFunction(void* pv);       
        long                        NotifyManager(int NotifyType);
        virtual long        WorkFunc(void* pUsrData);

private:
        long Init(const pthread_attr_t *pAttr, void *(*start_routine)(void *), void *pArg, bool IsCreateSuspend);


        friend MHANDLE CreateThread(const pthread_attr_t *pAttr, void *(*start_routine)(void *), void *pArg, bool IsCreateSuspend);

};



typedef struct _ID_INDEX_MAP
{
        long objID;
        bool bValid;

}IIMap;





class MHandleManager
{
public:
        MHandleManager(MHANDLE* pHandles,int nCounts);
        virtual ~MHandleManager();
        long RecieveNotify(MHANDLE pHandle,int nNotifyType);
        long WaitForHandles(bool bWaitForAll,long nWaitMillionSecond= 0x7FFFFFFF);
private:       
       
        MCritSec  m_NotifyLock;
        MCritSec  m_ConstructLock;
        //sem_t m_semComplete;
        MPSemaphoreID m_semComplete;
       
        MHANDLE* m_pHandle;
        int m_nHandleCounts;
       
        IIMap* m_pSignalInfoList;

        int    m_nNoSignalInfoCounts;
       
        bool   m_bTimeFlag;
        bool   m_bIsFirstSignal;
        long   m_lFirstSignalIndex;
       
        //void  WaitTimeOver();
       
       
        friend class MHBase;
       
};

MHANDLE CreateEvent(bool bManaulReset,bool bInitState);
void    SetEvent(MHANDLE event);
void    ResetEvent(MHANDLE event);
void    PulseEvent(MHANDLE event);
MHANDLE CreateSemaphore(long nInitSigs,long nMaxSigs);
void    ReleaseSemaphore(MHANDLE semaphore,long nSigCounts,long* lRet=NULL);

MHANDLE  CreateMutex(bool bInitState);
void    ReleaseMutex(MHANDLE mutex);





MHANDLE CreateThread(const pthread_attr_t *pAttr, void *(*start_routine)(void *), void *pArg, bool IsCreateSuspend);
long    ResumeThread(MHANDLE pthread);
long    SuspendThread(MHANDLE pthread);

void    CloseHandle(MHANDLE handle);


#define WAIT_FAILED -29296
long    WaitForMultipleObjects(int nCounts,MHANDLE* pHandle,bool IsAll,long lMillionSeconds);
long    WaitForSingleObject(MHANDLE Handle,long lMillionSeconds);






#endif //_M_THREAD_BASEOBJ_DEF_H_
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-9-5 16:30:01 | 显示全部楼层
我也遇到了!
下面的是有一个信号量通知就返回,而所有信号量都通知到菜返回的也这类似
struct timespec mt={0,0};
while(1){
    if(sem_timedwait(signal1,&mt)){
         res = 0;break;
    }
    if(sem_timedwait(sinal2,&mt)){
         res = 1;break;
    }
}
回复

使用道具 举报

0

主题

2

帖子

2.00

积分

新手上路

Rank: 1

积分
2.00
发表于 2020-9-5 16:45:01 | 显示全部楼层
也可以用 sem_trywait(); 返回值 0等待成功,-1 信号量不能立即作出反映,失败。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表