锁定Linux串行端口

时间:2013-07-31 20:49:54

标签: c linux locking serial-port

我有一个问题,我正试图解决Linux中的串口问题。我能够打开,读取和关闭端口就好了。但是,我想确保我是唯一一个在任何时候从港口读/写的人。

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

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

结果,我想知道是否有任何方法可以解决问题。从我的程序的角度来看,如果两次调用open()在同一个端口上成功,那么这并不是什么大问题,因为程序员应该知道它们造成的欢闹。但是,我只想确保当我打开一个端口时,我是唯一可以访问它的进程。

感谢您的帮助。

2 个答案:

答案 0 :(得分:11)

在Linux中,您可以使用TIOCEXCL TTY ioctl阻止设备的其他open()成功(他们将-1返回errno==EBUSY,设备或资源忙)。这仅适用于终端和串行设备,但不依赖于建议锁定。

例如:

#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;
}

希望这有帮助。

答案 1 :(得分:0)

我能够使用flock()函数解决问题。由于某种原因,使用结构和fcntl()对我来说不起作用。使用flock()我可以添加两行代码并解决我的问题。