![](/img/trans.png)
[英]How to ping-pong between parent and child processes in c on linux
[英]How to ping /dev/watchdog from 2 processes?
在 Linux(在 ARM 上运行)中,有一个进程对/dev/watchdog/
有一个打开的 fd,并且每隔几秒发送一个ioctl()
作为保持活动状态:
while (1) {
ioctl(fd, WDIOC_KEEPALIVE, 0);
sleep(10);
}
我也想从另一个进程发送保持活动状态,但我无法打开另一个 fd 到/dev/watchdog/
:当我尝试回显到/dev/watchdog/
我收到错误“设备或资源繁忙”。
我在哪里可以看到看门狗被定义为一次只能处理 1 个进程? (我在另一个 Linux 中看到某些进程可以打开 fd 到/dev/watchdog/
)。
我该怎么做才能从 2 个进程中喂养看门狗?
由于/dev/watchdog
在内核中的实现,只有一个进程可以同时使用它,所以从两个不同的进程打开/dev/watchdog
是不可能的。
您可以在 Linux 内核的源代码中看到这一点,特别是在drivers/watchdog/watchdog_dev.c
。 这是相关的代码片段:
/*
* watchdog_open: open the /dev/watchdog* devices.
* @inode: inode of device
* @file: file handle to device
*
* When the /dev/watchdog* device gets opened, we start the watchdog.
* Watch out: the /dev/watchdog device is single open, so we make sure
* it can only be opened once.
*/
static int watchdog_open(struct inode *inode, struct file *file)
{
/* ... */
/* the watchdog is single open! */
if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status))
return -EBUSY;
/* ... */
如果您想从两个不同的进程提供看门狗,您可以通过创建一个简单的“主”程序来解决这个问题,该程序与看门狗对话,同时根据需要编排两个子进程。 这可以通过不同的方式完成(管道、套接字、线程等)。 每个子进程一个popen()
是最简单的方法。
这是一个工作示例master.c
:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>
int main(int argc, char **argv) {
int watchdog_fd;
FILE *child1_fp, *child2_fp;
if (argc != 3 || !argv[1] || !*argv[1] || !argv[2] || !*argv[2]) {
fprintf(stderr, "Usage: %s 'CHILD_1_COMMAND' 'CHILD_2_COMMAND'\n", argv[0]);
return 1;
}
// Open a fd to talk to the watchdog.
watchdog_fd = open("/dev/watchdog", O_RDWR);
if (watchdog_fd == -1) {
perror("open failed");
return 1;
}
// Start the first process.
child1_fp = popen(argv[1], "r");
if (child1_fp == NULL) {
perror("popen (1) failed");
return 1;
}
// Start the second process.
child2_fp = popen(argv[2], "r");
if (child2_fp == NULL) {
perror("popen (2) failed");
return 1;
}
while (1) {
char tmp;
size_t count;
// Get one byte of data from each of the two processes.
count = fread(&tmp, 1, 1, child1_fp);
count += fread(&tmp, 1, 1, child2_fp);
// If both processes provided the data, ping the watchdog.
if (count == 2) {
if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
perror("ioctl failed");
}
}
return 0;
}
还有两个相同的程序ac
和bc
仅用于测试目的:
#include <stdio.h>
#include <unistd.h>
int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
while (1) {
putchar('x');
sleep(10);
}
}
编译并运行:
$ gcc -o master master.c
$ gcc -o a a.c
$ gcc -o b b.c
$ ./master ./a ./b
在上面的示例代码中,当且仅当两个孩子还活着并且正在运行时, master
ping 看门狗:如果两个孩子中的一个挂了或死了,master 将停止 ping 看门狗。 但是,重新设计逻辑以使其工作方式不同很简单,并且使其与两个以上的子进程一起工作也很简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.