锁定Linux串口

7

我有一个问题,正在尝试解决Linux中的串口问题。我能够很好地打开、读取和关闭端口。然而,我想确保在任何给定时间,只有我能够读写该端口。

我认为在调用open()函数后已经为我完成了这个任务。但是,在我的程序中,我可以多次调用同一端口上的open()。我还可以拥有两个同时从同一端口读取的线程。

我试图使用flock()来解决这个问题,但仍然存在相同的问题。这是因为两个系统调用都来自相同的pid,即使每组打开和读取都涉及不同的文件描述符?记录一下,两个open()调用确实返回了有效的文件描述符。

因此,我想知道是否有任何方法可以解决我的问题。从我的程序的角度来看,如果在同一端口上成功调用两次open(),这并不是一个大问题,因为程序员应该意识到他们所引起的滑稽。然而,我只想确保当我打开一个端口时,我是唯一能够访问它的进程。

感谢您的帮助。


我已经询问了有关在Linux中锁定串口和其他设备的“最佳实践”方法的问题。链接 - Craig McQueen
2个回答

17
在Linux中,您可以使用TIOCEXCL TTY ioctl停止其他对设备的open()成功(它们将返回-1并带有errno==EBUSY,设备或资源忙)。 这仅适用于终端和串行设备,但不依赖于advisory锁定。 例如:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>

int open_device(const char *const device)
{
    int descriptor, result;

    if (!device || !*device) {
        errno = EINVAL;
        return -1;
    }

    do {
        descriptor = open(device, O_RDWR | O_NOCTTY);
    } while (descriptor == -1 && errno == EINTR);
    if (descriptor == -1)
        return -1;

    if (ioctl(descriptor, TIOCEXCL)) {
        const int saved_errno = errno;
        do {
            result = close(descriptor);
        } while (result == -1 && errno == EINTR);
        errno = saved_errno;
        return -1;
    }

    return descriptor;
}
希望这能帮到你。

希望这有所帮助。


我在已经打开的端口下,以root身份没有收到任何EBUSY错误。 - Mehmet Fide

0

我通过使用flock()函数解决了问题。 结构体和fcntl()的使用对我来说出了一些问题。 通过使用flock(),我能够添加两行代码并解决我的问题。


3
这个答案让人感到困惑,因为在你的问题中你说你尝试使用了flock()但它没有起作用。现在你又说flock()是解决方案。这是怎么回事? 提示:此翻译仅供参考,具体语言表达仍需根据上下文和语境进行调整。 - Craig McQueen
你的原始问题中可能是指 fcntl() 没有起作用,而不是 flock(),这种情况是否可能? - Craig McQueen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接