设为首页 加入收藏

TOP

Linux下模拟一个简易的消息机制(一)
2014-11-23 21:36:08 来源: 作者: 【 】 浏览:38
Tags:Linux 模拟 一个 简易 消息 机制

消息机制是WIN32的核心,本质就是一个消息结构的链表。


声明


#define MSG_ERROR -1


#define MSG_SUCCEED 0 #define MSG_TRUE 1


#define MSG_FALSE 0 #define PM_NOREMOVE 0x00


#define PM_REMOVE 0x01 typedef unsigned longWPARAM; typedef unsigned longLPARAM; typedef unsigned intUINT; typedef intMSG_BOOL;//这个返回值很二 不要喷我... typedef struct


{


UINTmessage;//消息类型 UINTidThread;//线程ID WPARAMwParam;


LPARAMlParam;


}MSG;


typedef MSG* LPMSG;


typedef struct NODE


{


MSG data;


struct NODE* next;


}MSG_NODE;


void SetupMessage();//启动消息队列 void TerminalMessage();//终止消息队列


MSG_BOOL PeekMessage( LPMSG lpMsg,


UINT hWnd,


UINT wMsgFilterMin,


UINT wMsgFilterMax,


UINT wRemoveMsg);



MSG_BOOL PostThreadMessage( UINT idThread,


UINT msg,


WPARAM wParam,


LPARAM lParam);


实现


#include "msg.h" #include


#include


#include


#include


#include static MSG_NODE * g_message_queue = NULL;


static MSG_NODE* msg_create()


{


MSG_NODE* pHead = calloc(sizeof(MSG_NODE),1);


return pHead;


}


static void msg_destroy(MSG_NODE* pHead)


{


MSG_NODE* pNode = NULL;


if(pHead)


{


pNode = pHead->next;


while(pNode)


{


pHead->next = pNode->next;


printf("Free Node:%p\n",pNode);


free(pNode);


pNode = pHead->next;


}


free(pHead);


printf("Free Head Node:%p\n",pHead);


}


}


//定位到消息列表尾部


static MSG_NODE* msg_tail(MSG_NODE* pHead)


{


MSG_NODE* pTail = NULL;



if(!pHead) return NULL;


pTail = pHead;


while(pTail->next) pTail = pTail->next;


return pTail;


}


//尾部插入一个消息结点


static int msg_push_back(MSG_NODE* pHead, MSG_NODE* pNode)


{


MSG_NODE* pTail = NULL;



if( !pHead || !pNode) return MSG_ERROR;



pTail = msg_tail(pHead);


if(pTail)


{


pTail->next = pNode;


pNode->next = NULL;


return MSG_SUCCEED;


}


return MSG_ERROR;


}


//启动


void SetupMessage()


{


if(!g_message_queue)


{


g_message_queue = msg_create();


assert(g_message_queue);


}


}


//终止


void TerminalMessage()


{


msg_destroy(g_message_queue);


g_message_queue = NULL;


}




MSG_BOOL PostThreadMessage(UINT idThread,UINT msg, WPARAM wParam, LPARAM lParam)


{


MSG_NODE* pNode = NULL;



if( !g_message_queue && (msg < 0) ) return MSG_FALSE;



pNode = calloc(sizeof(MSG_NODE),1);


if (pNode)


{


pNode->data.message = msg;


pNode->data.idThread = (!idThread) pthread_self():idThread;//如果ID是0 默认为当前线程 pNode->data.wParam = wParam;


pNode->data.lParam = lParam;


pNode->next = NULL;


return (msg_push_back(g_message_queue,pNode) == MSG_SUCCEED) MSG_TRUE:MSG_FALSE;


}


return MSG_FALSE;


}


//第二个参数完成为了函数"像" Win32 API 没有用处,LINUX没有窗口句柄这一说 MSG_BOOL PeekMessage(LPMSG lpMsg,UINT HWND,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg)


{


MSG_NODE* pNode = NULL;


MSG_NODE* pPreNode = NULL;//保存前一个结点


if( !g_message_queue && lpMsg) return MSG_FALSE;



pPreNode = g_message_queue;


pNode = g_message_queue->next;



/*


*不要喷我 用这么多goto啊 只是为了 不要写一堆重复的代码


*/


while(pNode)


{


if(pNode->data.idThread != (UINT)pthread_self() )


{


goto NEXT;


}



if(wMsgFilterMin|wMsgFilterMax)


{


if( pNode->data.message >= wMsgFilterMin &&


pNode->data.message <= wMsgFilterMax )


{


goto GET_MSG;


}


}


else


{


goto GET_MSG;


}



NEXT:


pPreNode = pNode;


pNode = pNode->next;


continue;



GET_MSG:


memcpy(lpMsg,&pNode->data,sizeof(MSG) );


if(wRemoveMsg == PM_REMOVE)//删除消息链表结点 {


pPreNode->next = pNode->next;//前驱结点关联后继结点 防止链表截断 free(pNode);//释放当前消息链表结点 }


return MSG_TRUE;


}


return MSG_TRUE;


}


测试用例



#include


#include


#include "msg.h"


int main(int argc,char** argv)


{


int i=0;


MSG msg;



SetupMessage();



for(i=0;i<10;i++)


{


PostThreadMessage(0,1000+i, 100+i, 200+i);


}



while(1)


{


PeekMessage(&msg,0,0,0,PM_REMOVE);


printf("ID:%u,WPARAM:%lu,LPARAM:%lu\n",msg.message

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux串口IO模式的一些心得 下一篇Linux 内核的测试和调试(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: