>  기사  >  시스템 튜토리얼  >  Linux IPC POSIX 메시지 큐: 안정적인 메시지 전달을 위한 간단한 방법

Linux IPC POSIX 메시지 큐: 안정적인 메시지 전달을 위한 간단한 방법

PHPz
PHPz앞으로
2024-02-10 14:45:25759검색

Linux 시스템은 다중 작업의 동시 실행을 지원하는 운영 체제로, 동시에 여러 프로세스를 실행할 수 있어 시스템 활용도와 효율성이 향상됩니다. 그러나 이러한 프로세스 간에 데이터 교환 및 협업이 필요한 경우 신호, 공유 메모리, 세마포어 등과 같은 일부 프로세스 간 통신(IPC) 방법을 사용해야 합니다. 그 중 POSIX 메시지 큐는 비교적 간단하고 안정적인 IPC 방식으로, 두 개 이상의 프로세스가 메시지의 내용과 형식을 고려하지 않고 큐를 통해 메시지를 전송할 수 있습니다. 이 기사에서는 메시지 큐의 생성, 열기, 전송, 수신, 닫기 및 삭제를 포함하여 Linux 시스템에서 POSIX 메시지 큐의 방법을 소개합니다.

Linux IPC POSIX 消息队列:一种实现可靠消息传递的简单方式

모델:

으아악

POSIX mq VS Sys V mq

의 장점
  • 더 간단한 파일 기반 애플리케이션 인터페이스
  • 메시지 우선순위에 대한 완벽한 지원(우선순위는 궁극적으로 대기열에서 메시지의 위치를 ​​결정합니다)
  • 신호 또는 스레드 생성을 통해 구현되는 메시지 도착의 비동기 알림을 완벽하게 지원합니다
  • 보내기 및 받기 작업을 차단하는 시간 초과 메커니즘

메시지 대기열 이름

다음에서 알 수 있습니다. 메시지 대기열은 '/somename' 형식의 이름으로 고유하게 식별됩니다. 이름 문자열의 최대 길이는 NAME_MAX(예: 255)를 향할 수 없습니다. $man mq_overview 대기열 이름.

mq_open() 으아악

offlag 다음 중 하나를 포함해야 합니다:

  • O_RDONLY는 메시지만 수신하기 위해 메시지 대기열을 여는 것을 의미합니다
  • O_WRONLY는 메시지만 보내기 위해 메시지 대기열을 여는 것을 의미합니다
  • O_RDWR은 수신 및 전송이 가능한 형태로 메시지 대기열을 여는 것을 의미합니다
비트 ORed 가능:

  • O_NONBLOCK비차단 모드에서 메시지 대기열 열기
  • O_CREAT메시지 큐가 없으면 메시지 큐 소유자의 UID는 호출 프로세스의 유효 UID로 설정되고 GID는 호출 프로세스의 유효 GID로 설정됩니다
  • O_EXCL메시지 큐가 생성되었는지 확인하세요. 메시지 큐가 이미 존재하면 오류가 발생합니다

modeoflag에 O_CREAT가 있으면 mode는 새로 생성된 메시지 대기열의 권한을 나타내는 데 사용됩니다.
attr oflag에 O_CREAT가 있으면 attr은 메시지 대기열의 속성을 나타냅니다. attr이 NULL입니다. , 기본값이 됩니다. 구성 메시지 큐를 설정하세요(자세한 내용은 mq_overview(7).)

mq_setattr() / mq_getattr() 으아악

mqattr 구조

struct mq_attr {
    long mq_flags;      /* Flags: 0 or O_NONBLOCK */
    long mq_maxmsg;     /* Max. # of messages on queue */
    long mq_msgsize;    /* Max. message size (bytes) */
    long mq_curmsgs;    /* # of messages currently in queue */
};

mq_send() / mq_timesend()

//发送消息到mqdes指向的消息队列。成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio);

//如果消息队列满
#include        //额外的header
int mq_timedsend(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio,
const struct timespec *abs_timeout);

msg_len msg_ptr指向的消息队列的长度,这个长度必须msg_prio 一个用于表示消息优先级的非0整数,消息按照优先级递减的顺序被放置在消息队列中,同样优先级的消息,新的消息在老的之后,如果消息队列满了,就进入blocked状态,新的消息必须等到消息队列有空间了进入,或者调用被signal中断了。如果flag里有O_NOBLOCK选项,则此时会直接报错
abs_timeout:如果消息队列满了,那么就根据abs_timeout指向的结构体表明的时间进行锁定,里面的时间是从970-01-01 00:00:00 +0000 (UTC)开始按微秒计量的时间,如果时间到了,那么mq_timesend()立即返回

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

mq_receive()/mq_timedreceive()

//从消息队列中取出优先级最高的里面的最老的消息,成功返回消息取出消息的大小,失败返回-1设errno
//具体功能参照mq_send()/mq_timesend()
//Link with -lrt.
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
#include        //额外的header
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
 unsigned int *msg_prio, const struct timespec *abs_timeout);

mq_notify()

//允许调用进程注册或去注册同步来消息的通知,成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_notify(mqd_t mqdes, const struct sigevent *sevp);

sevp指向sigevent的指针

  • 如果sevp不是NULL,那么这个函数就将调用进程注册到通知进程,只有一个进程可以被注册为通知进程
  • 如果sevp是NULL且当前进程已经被注册过了,则去注册,以便其他进程注册
union sigval {                  /* Data passed with notification */
    int     sival_int;          /* Integer value */
    void*   sival_ptr;          /* Pointer value */
};
struct sigevent {
    int     sigev_notify;       /* Notification method */
    int     sigev_signo;        /* Notification signal */
    union sigval    sigev_value;    /* Data passed with notification */
    void(*sigev_notify_function) (union sigval); //Function used for thread notification
 (SIGEV_THREAD)
    void*   sigev_notify_attributes;    // Attributes for notification thread (SIGEV_THREAD)
    pid_t   sigev_notify_thread_id;     /* ID of thread to signal (SIGEV_THREAD_ID) */
};

sigev_notify使用下列的宏进行配置:

  • SIGEV_NONE调用进程仍旧被注册,但是有消息来的时候什么都不通知
  • SIGEV_SIGNAL通过给调用进程发送sigev_signo指定的信号来通知进程有消息来了
  • SIGEV_THREAD一旦有消息到了,就激活sigev_notify_function作为新的线程的启动函数

mq_close()

//关闭消息队列描述符mqdes,如果有进程存在针对这个队列的notification request,那么也会被移除

//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_close(mqd_t mqdes);

mq_unlink():

//移除队列名指定的消息队列,一旦最后一个进程关闭了针对这个消息队列的描述符,就会销毁这个消息队列
//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_unlink(const char *name);

本文介绍了Linux系统中POSIX 消息队列的方法,包括消息队列的创建、打开、发送、接收、关闭和删除等方面。通过了解和掌握这些知识,我们可以更好地使用POSIX 消息队列来实现进程间通信,提高系统的稳定性和效率。当然,Linux系统中POSIX 消息队列还有很多其他的特性和用法,需要我们不断地学习和研究。希望本文能给你带来一些启发和帮助。

위 내용은 Linux IPC POSIX 메시지 큐: 안정적인 메시지 전달을 위한 간단한 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제