在Linux环境下面,经常使用“消息队列”(mq_open、mq_send、mq_receive等),它非常好用,因为现在的工作中经常处理多线程,要处理好多线程,免不了要有“排队”的处理,上述的消息队列可以很好的实现FIFO类型的队列操作。
Linux这么好用的消息队列,在Windows使用有对应呢?答案有:邮件槽,下面来看一个具体的示例,客户端线程快速将数据压入“队列”,服务器线程慢速取出数据,只要“队列”中的数据不丢,就算实现了想要的功能:
#include "stdafx.h"
#include "TestCmd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
#define MAIL_SLOT_NAME ("\\\\.\\Mailslot\\mailslot_abc")
typedef struct
{
int x;
int y;
char str[100];
}USER_TYPE;
UINT FuncClient(LPVOID pParam )
{
HANDLE hFile;
hFile = CreateFile(MAIL_SLOT_NAME, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile失败: %s ", MAIL_SLOT_NAME);
return 1;
}
DWORD dwWriteBytes;
int i=0;
USER_TYPE u_t={0};
for(i = 1; i <= 10; i++)
{
//创建自定义的数据变量并赋值
u_t.x=i;
u_t.y=i*100;
sprintf(u_t.str, "Hello:%d", i);
WriteFile(hFile, &u_t, sizeof(u_t), &dwWriteBytes, NULL);
Sleep(10); //模拟快速入队
}
return 0L;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
HANDLE hMailslot;
hMailslot = CreateMailslot(MAIL_SLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, NULL);
if(hMailslot == INVALID_HANDLE_VALUE)
{
printf("创建邮件槽失败: %d \r\n", GetLastError());
return 1;
}
//创建客户端
AfxBeginThread(FuncClient, NULL);
//服务器程序(或者说线程)在运行
DWORD dwReadBytes = 0;
USER_TYPE u_t;
while(ReadFile(hMailslot, &u_t, 10000, &dwReadBytes, NULL))
{
printf("%d, %d, %s\r\n", u_t.x, u_t.y, u_t.str);
Sleep(1000);//服务器的取数据延时大于客户端,检查是否能从队列中取出?
}
return 0;
CloseHandle(hMailslot);
}
return nRetCode;
}