串行通信C/C++ Linux线程安全吗?

5
我的问题很简单。在Linux下,从串口读写是否是线程安全的?我可以同时从不同的线程中读取和写入吗?甚至可以同时进行两次写入吗?虽然我没有打算这样做,但对其他人可能会很有趣。我只有一个读取数据的线程和一个写入数据的线程。
关于这个话题,很少有相关的信息。
更详细的说,我正在使用通过open()获取的文件描述符上的write()和read()函数,并且同时进行。
谢谢大家!
Roel
1个回答

3
这涉及两个方面:
  1. C实现的操作
  2. 内核操作
关于内核,我非常确定它要么支持此操作,要么引发相应的错误,否则这将太容易被利用。read()的C实现只是一个系统调用包装器(参见what happens after read is called for a Linux socket),因此这并没有改变什么。然而,我仍然没有看到任何保证文件记录在那里,所以这不可靠。
如果您真的想要两个线程,我建议您使用stdio函数(fopen/fread/fwrite/fclose),因为在这里您可以利用glibc在内部使用互斥锁来同步这些调用的事实。
但是,如果您在一个线程中进行阻塞读取,则另一个线程可能会被阻塞等待写入某些内容。这可能会导致死锁。解决方法是使用select()检测何时有一些数据准备好被读取或缓冲区空间可写。虽然这是在单个线程中完成的,但最初的代码稍微大一些,但最终这种方法更容易、更清洁,特别是如果涉及多个流。

1
非常有趣的答案,谢谢。在我的情况下,将有1个读取线程和1个写入线程。理论上,我甚至可以合并这两个线程。但是将其放在单独的线程中更加整洁。理论上,我还可以在读取和写入函数周围放置std互斥锁。然后我就不必重写stdio函数了。 - Silver
这是否意味着从多个线程同时调用写同一个文件描述符会导致竞态条件? - undefined
是的。引用man 2 write:“成功的write()可能传输少于count字节”。这意味着你必须在循环中写入数据,这又意味着两个这样的循环可能交错写入字节,导致数据损坏。 - undefined

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