假设有两个进程, 一个进程专注于串口信号的检测, 一个进程专注于根据不同信号进行对应功能的控制。
这个时候需要进行进程间通信。我选择了消息队列进行尝试, 消息队列对于命名管道的一个好处是, 即使进程挂了, 消息队列依然还在, 重启后还能对原来的队列进行读写, 数据因而不会丢失。
在Beaglebone Black的debian7.5系统上实现运行后, 发现MQ的队列长度默认最大为16。 这个貌似有些小。。。可以通过如下两种方式来修改队列长度:
(1)临时修改:
root@beaglebone:~# sysctl -w kernel.msgmni=128
(2)永久修改, 每次系统在启动时修改该值:
root@beaglebone:~# vim /etc/sysctl.conf
打开后在末尾加上如下一行:
kernel.msgmni = 128
查看修改的效果可以通过ipcs -l命令查看, 示例:
root@beaglebone:~# ipcs -l
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 32768
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
------ Messages Limits --------
max queues system wide = 128
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384
其中max queues system wide 就是刚刚修改的队列长度。
以下是使用消息队列进行通信的示例:
(1)消息发送
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <unistd.h>
#define ST_IPC_SIGNAL_KEY 10001
IPC_MSG_MAX_LEN 256
int MSG_QUEUE_ID;
typedef struct _msgform
{
int mtype;
pid_t pid;
char mtext[IPC_MSG_MAX_LEN];
} MSG_FORM;
void send_MQ(int msg_size, char* msg_content)
{
static int isFirstInitQID = 1;
if (isFirstInitQID == 1)
{
MSG_QUEUE_ID=msgget(ST_IPC_SIGNAL_KEY, 0777|IPC_CREAT);
if (MSG_QUEUE_ID > 0)
{
isFirstInitQID = 0;
printf("MSG_QUEUE_ID has been initialized successfully.\n");
}
}
MSG_FORM msg;
msg.mtype = 100;
msg.pid = getpid();
memset(msg.mtext, 0, IPC_MSG_MAX_LEN);
strncpy(msg.mtext, msg_content, msg_size);
int ret = msgsnd(MSG_QUEUE_ID, &msg, 512, 0);
printf("send_cmd_msg ret=%d, msg=%s\n", ret, msg.mtext);
}
(2)消息接收
void on_recv_ipc_signal()
{
printf("Begin to process receive messages.\n");
while(1)
{
MSG_FORM msg;
int msgqid=msgget(ST_IPC_SIGNAL_KEY, 0777|IPC_CREAT);
msgrcv(msgqid, &msg, 512, 0, 0);
printf("Recv msg from MQ: %s\n", msg.mtext);
// TODO: process the commands from message-queue
// handle_ipc_msg(&msg);
usleep(10000);
}
printf("End of the processing of message arrival.\n");
}