5

我有一个关于 Linux 串行端口的问题正在尝试解决。我可以很好地打开、读取和关闭端口。但是,我想确保我是在任何给定时间从端口读取/写入的唯一人。

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

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

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

谢谢您的帮助。

4

2 回答 2

15

在 Linux 中,您可以使用TIOCEXCLTTY ioctl 来阻止open()设备的其他 s 成功(它们将返回-1errno==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;
}

希望这可以帮助。

于 2013-08-01T01:17:41.303 回答
0

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

于 2013-07-31T21:17:12.313 回答