在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

目录
相关文章
|
26天前
|
消息中间件 并行计算 安全
进程、线程、协程
【10月更文挑战第16天】进程、线程和协程是计算机程序执行的三种基本形式。进程是操作系统资源分配和调度的基本单位,具有独立的内存空间,稳定性高但资源消耗大。线程是进程内的执行单元,共享内存,轻量级且并发性好,但同步复杂。协程是用户态的轻量级调度单位,适用于高并发和IO密集型任务,资源消耗最小,但不支持多核并行。
40 1
|
1月前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
169 2
|
5天前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
10天前
|
Linux 调度 C语言
深入理解操作系统:进程和线程的管理
【10月更文挑战第32天】本文旨在通过浅显易懂的语言和实际代码示例,带领读者探索操作系统中进程与线程的奥秘。我们将从基础知识出发,逐步深入到它们在操作系统中的实现和管理机制,最终通过实践加深对这一核心概念的理解。无论你是编程新手还是希望复习相关知识的资深开发者,这篇文章都将为你提供有价值的见解。
|
7天前
|
Java
java小知识—进程和线程
进程 进程是程序的一次执行过程,是系统运行的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 线程 线程,与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间做切换工作时,负担要比
17 1
|
12天前
深入理解操作系统:进程与线程的管理
【10月更文挑战第30天】操作系统是计算机系统的核心,它负责管理计算机硬件资源,为应用程序提供基础服务。本文将深入探讨操作系统中进程和线程的概念、区别以及它们在资源管理中的作用。通过本文的学习,读者将能够更好地理解操作系统的工作原理,并掌握进程和线程的管理技巧。
27 2
|
14天前
|
调度 Python
深入浅出操作系统:进程与线程的奥秘
【10月更文挑战第28天】在数字世界的幕后,操作系统悄无声息地扮演着关键角色。本文将拨开迷雾,深入探讨操作系统中的两个基本概念——进程和线程。我们将通过生动的比喻和直观的解释,揭示它们之间的差异与联系,并展示如何在实际应用中灵活运用这些知识。准备好了吗?让我们开始这段揭秘之旅!
|
24天前
|
Python
Python中的多线程与多进程
本文将探讨Python中多线程和多进程的基本概念、使用场景以及实现方式。通过对比分析,我们将了解何时使用多线程或多进程更为合适,并提供一些实用的代码示例来帮助读者更好地理解这两种并发编程技术。
|
27天前
|
消息中间件 并行计算 安全
进程、线程、协程
【10月更文挑战第15天】进程、线程和协程是操作系统中三种不同的执行单元。进程是资源分配和调度的基本单位,每个进程有独立的内存空间;线程是进程内的执行路径,共享进程资源,切换成本较低;协程则更轻量,由用户态调度,适合处理高并发和IO密集型任务。进程提供高隔离性和安全性,线程支持高并发,协程则在资源消耗和调度灵活性方面表现优异。
44 2
|
1月前
|
监控 安全 算法
线程死循环确实是多线程编程中的一个常见问题,它可能导致应用程序性能下降,甚至使整个系统变得不稳定。
线程死循环是多线程编程中常见的问题,可能导致性能下降或系统不稳定。通过代码审查、静态分析、日志监控、设置超时、使用锁机制、测试、选择线程安全的数据结构、限制线程数、使用现代并发库及培训,可有效预防和解决死循环问题。
49 1