在Windows系统上实现轻量级的线程间及进程间消息队列

简介: Windows没有message queue累世的IPC内核对象,使得在在处理IPC时少了一种传递消息的手段。利用Windows的Naming Object可以实现一套简单的Inter-Thread消息队列。

Windows没有message queue累世的IPC内核对象,使得在在处理IPC时少了一种传递消息的手段。

利用Windows的Naming Object可以实现一套简单的Inter-Thread消息队列。这里并不使用socket,因为一旦使用socket,就得负责port管理,很麻烦,另外在对外接口上也很难和vxworks等msgq接口保持一致。所以后来干脆把接口定义成了类vxworks接口。

偶然间看了一眼云风的http://blog.codingnow.com/中关于windows进程间内存共享的blog,决定将其改成同时支持Inter-Thread和Inter-Process Message Queue的有名对象。

目前接口定义如下, 可下载包见 tinymq-binary-0.1.zip 以及测试 demo-0.1.zip

/* msgQueue.h - declaration of VxWorks-like message queue */

/*
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is a part of the virtual operating system package.
 * No warranty is given; refer to the file DISCLAIMER within the package.
 *
 */

/*
modification history
--------------------
01a,11nov11,sgu  created
*/

/*
DESCRIPTION
This module implements the functions for a message queue. The message queue
manipulation functions in this file are similar with the Wind River VxWorks
kernel message queue interfaces.

The memory architecture for a message queue:
----------------   -----------------------------------------------------------
| local memory |-->|                     shared memory                       |
----------------   -----------------------------------------------------------
       ^                                     ^
       |                                     |
----------------   -----------------------------------------------------------
|    MSG_Q     |   | MSG_SM | MSG_NODE list |       message queue data       |
----------------   -----------------------------------------------------------
                                    ^                         ^
                                    |                         |
             ---------------------------------------------    |
             | MSG_NODE1 | MSG_NODE2 | ... | MSG_NODE(N) |    |
             ---------------------------------------------    |
                                                              |
                                              ---------------------------------
                                              | data1 | data2 | ... | data(N) |
                                              ---------------------------------

Each message queue in memory can be divided into two parts, local memory and
shared memory, but these two parts are not closed by. The local memory can be
accessed in an process, also can be accessed between threads in the process.
The shared memory can be accessed between threads in a process if the message
queue name is NULL; or can be accessed between processes if the message queue
name is not NULL. There is one data structure MSG_Q in local memory; three data
structures -- MSG_SM, MSG_NODE list and message queue data in shared memory.
The structure MSG_Q saves the kernel objects handlers and the shared memory
address; MSG_SM saves the message queue attributes; MSG_NODE list saves all the
nodes for the message queue, and each node saves all attribute of each message;
the message queue data area saves all the data for all the message. All the
structures defined below.

If you meet some problem with this module, please feel free to contact
me via e-mail: gushengyuan2002@163.com
*/

#ifndef _MSG_QUEUE_H_
#define _MSG_QUEUE_H_

/* defines */

/* wait forever for timeout flag */
#define WAIT_FOREVER    -1

/* version string length */
#define VERSION_LEN     8

/* create an inter-thread message queue */
#define msgQCreate(maxMsgs, maxMsgLength, options) \
        msgQCreateEx(maxMsgs, maxMsgLength, options, NULL)

/* typedefs */

typedef unsigned int UINT;
typedef void* MSG_Q_ID;    /* message queue identify */

/* message queue options for task waiting for a message */
enum MSG_Q_OPTION{
    MSG_Q_FIFO     = 0x0000,
    MSG_Q_PRIORITY = 0x0001
};

/* message sending options for sending a message */
enum MSG_Q_PRIORITY{
    MSG_PRI_NORMAL = 0x0000, /* put the message at the end of the queue */
    MSG_PRI_URGENT = 0x0001  /* put the message at the frond of the queue */
};

/* message queue status */
typedef struct tagMSG_Q_STAT {
    char version[VERSION_LEN];  /* library version */
    int maxMsgs;                /* max messages that can be queued */
    UINT maxMsgLength;          /* max bytes in a message */
    int options;                /* message queue options */
    int msgNum;                 /* message number in the queue */
    int sendTimes;              /* number of sent */
    int recvTimes;              /* number of received */
}MSG_Q_STAT;

#ifdef __cplusplus
extern "C"
{
#endif

/* declarations */

/*******************************************************************************
 * msgQCreateEx - create a message queue, queue pended tasks in FIFO order
 *
 * create a message queue, queue pended tasks in FIFO order.
 * <name> message name, if name equals NULL, create an inter-thread message
 * queue, or create an inter-process message queue.
 *
 * RETURNS: MSG_Q_ID when success or NULL otherwise.
 */
MSG_Q_ID msgQCreateEx
    (
    int maxMsgs,     /* max messages that can be queued */
    int maxMsgLength,/* max bytes in a message */
    int options,     /* message queue options, ignored on Windows platform */
    const char *name /* message name */
    );

/*******************************************************************************
 * msgQOpen - open a message queue
 *
 * open a message queue.
 *
 * RETURNS: MSG_Q_ID when success or NULL otherwise.
 */
MSG_Q_ID msgQOpen
    (
    const char * name   /* message name */
    );

/*******************************************************************************
 * msgQDelete - delete a message queue
 *
 * delete a message queue.
 *
 * RETURNS: 0 when success or -1 otherwise.
 */
int msgQDelete
    (
    MSG_Q_ID msgQId /* message queue to delete */
    );

/*******************************************************************************
 * msgQReceive - receive a message from a message queue
 *
 * receive a message from a message queue.
 *
 * RETURNS: 0 when success or -1 otherwise.
 */
int msgQReceive
    (
    MSG_Q_ID msgQId,  /* message queue from which to receive */
    char * buffer,    /* buffer to receive message */
    UINT maxNBytes,   /* length of buffer */
    int timeout       /* ticks to wait */
    );

/*******************************************************************************
 * msgQSend - send a message to a message queue
 *
 * send a message to a message queue.
 *
 * RETURNS: 0 when success or -1 otherwise.
 */
int msgQSend
    (
    MSG_Q_ID msgQId, /* message queue on which to send */
    char * buffer,   /* message to send */
    UINT nBytes,     /* length of message */
    int timeout,     /* ticks to wait */
    int priority     /* MSG_PRI_NORMAL or MSG_PRI_URGENT */
    );

/*******************************************************************************
 * msgQStat - get the status of message queue
 *
 * get the detail status of a message queue.
 *
 * RETURNS: 0 when success or -1 otherwise.
 */
int msgQStat
    (
    MSG_Q_ID msgQId,
    MSG_Q_STAT * msgQStatus
    );

/*******************************************************************************
 * msgQShow - show the status of message queue
 *
 * show the detail status of a message queue.
 *
 * RETURNS: 0 when success or -1 otherwise.
 */
int msgQShow
    (
    MSG_Q_ID msgQId
    );

#ifdef __cplusplus
}
#endif

#endif

目录
相关文章
|
11天前
如何隐藏windows10系统任务栏右下角的语言输入法图标?
如何隐藏windows10系统任务栏右下角的语言输入法图标?
|
23天前
|
安全 数据处理 C++
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角
102 3
|
9天前
|
调度 Windows
|
30天前
|
资源调度 算法 Linux
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
Linux进程/线程的调度机制介绍:详细解析Linux系统中进程/线程的调度优先级规则
49 0
|
2天前
|
消息中间件 存储 Java
深度探索:使用Apache Kafka构建高效Java消息队列处理系统
【4月更文挑战第17天】本文介绍了在Java环境下使用Apache Kafka进行消息队列处理的方法。Kafka是一个分布式流处理平台,采用发布/订阅模型,支持高效的消息生产和消费。文章详细讲解了Kafka的核心概念,包括主题、生产者和消费者,以及消息的存储和消费流程。此外,还展示了Java代码示例,说明如何创建生产者和消费者。最后,讨论了在高并发场景下的优化策略,如分区、消息压缩和批处理。通过理解和应用这些策略,可以构建高性能的消息系统。
|
23天前
|
存储 算法 Linux
【Linux 系统标准 进程资源】Linux 创建一个最基本的进程所需的资源分析,以及线程资源与之的差异
【Linux 系统标准 进程资源】Linux 创建一个最基本的进程所需的资源分析,以及线程资源与之的差异
25 0
|
27天前
|
监控 Linux Shell
【Shell 命令集合 系统管理 】⭐Linux 显示系统中的进程信息 procinfo命令 使用指南
【Shell 命令集合 系统管理 】⭐Linux 显示系统中的进程信息 procinfo命令 使用指南
26 0
|
消息中间件 监控 安全
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
43 0
|
API Windows
Windows Api学习笔记-设置线程的优先级
#include #include using namespace std; DWORD WINAPI ThreadIdle(LPVOID lpParam) { int i=0; while(i++
881 0
|
1月前
|
安全 数据安全/隐私保护 Windows
解锁安全之门,Windows Server 2019密码修改攻略大揭秘
解锁安全之门,Windows Server 2019密码修改攻略大揭秘