My question is quite simple. Is reading and writing from and to a serial port under Linux thread-safe? Can I read and write at the same time from different threads? Is it even possible to do 2 writes simultaneously? I'm not planning on doing so but this might be interesting for others. I just have one thread that reads and another one that writes.
我的问题很简单。在Linux线程安全的情况下,从串行端口读写吗?我可以同时从不同的线程读和写吗?是否有可能同时写2个?我不打算这么做,但这对其他人来说可能很有趣。我只有一个线程读,另一个线程写。
There is little to find about this topic.
这个话题没什么可找的。
More on detail—I am using write()
and read()
on a file descriptor that I obtained by open()
; and I am doing so simultaneously.
更多细节——我在open()获得的文件描述符上使用write()和read();我同时这么做。
Thanks all!
感谢所有!
Roel
Roel
1 个解决方案
#1
3
There are two aspects to this:
这有两个方面:
- What the C implementation does.
- C实现的作用。
- What the kernel does.
- 什么内核。
Concerning the kernel, I'm pretty sure that it will either support this or raise an according error, otherwise this would be too easy to exploit. The C implementation of read() is just a syscall wrapper (See what happens after read is called for a Linux socket), so this doesn't change anything. However, I still don't see any guarantees documented there, so this is not reliable.
关于内核,我非常确信它将支持这一点,或者产生一个相应的错误,否则这就太容易被利用了。read()的C实现只是一个syscall包装器(请参见read之后调用的Linux套接字),因此这不会改变任何东西。但是,我仍然没有看到任何保证文件,所以这是不可靠的。
If you really want two threads, I'd suggest that you stay with stdio functions (fopen/fread/fwrite/fclose), because here you can leverage the fact that the glibc synchronizes these calls with a mutex internally.
如果您确实需要两个线程,我建议您使用stdio函数(fopen/fread/fwrite/fclose),因为在这里您可以利用glibc在内部与互斥对象同步这些调用的事实。
However, if you are doing a blocking read in one thread, the other thread could be blocked waiting to write something. This could be a deadlock. A solution for that is to use select() to detect when there is some data ready to be read or buffer space to be written. This is done in a single thread though, but while the initial code is a bit larger, in the end this approach is easier and cleaner, even more so if multiple streams are involved.
但是,如果您正在一个线程中进行块读,那么另一个线程可能会被阻塞,等待编写一些东西。这可能是一个僵局。一种解决方案是使用select()来检测何时有一些数据准备被读取或要写入缓冲区空间。虽然这是在一个线程中完成的,但是虽然最初的代码有点大,但是最终这种方法更简单、更干净,如果涉及到多个流的话更是如此。
#1
3
There are two aspects to this:
这有两个方面:
- What the C implementation does.
- C实现的作用。
- What the kernel does.
- 什么内核。
Concerning the kernel, I'm pretty sure that it will either support this or raise an according error, otherwise this would be too easy to exploit. The C implementation of read() is just a syscall wrapper (See what happens after read is called for a Linux socket), so this doesn't change anything. However, I still don't see any guarantees documented there, so this is not reliable.
关于内核,我非常确信它将支持这一点,或者产生一个相应的错误,否则这就太容易被利用了。read()的C实现只是一个syscall包装器(请参见read之后调用的Linux套接字),因此这不会改变任何东西。但是,我仍然没有看到任何保证文件,所以这是不可靠的。
If you really want two threads, I'd suggest that you stay with stdio functions (fopen/fread/fwrite/fclose), because here you can leverage the fact that the glibc synchronizes these calls with a mutex internally.
如果您确实需要两个线程,我建议您使用stdio函数(fopen/fread/fwrite/fclose),因为在这里您可以利用glibc在内部与互斥对象同步这些调用的事实。
However, if you are doing a blocking read in one thread, the other thread could be blocked waiting to write something. This could be a deadlock. A solution for that is to use select() to detect when there is some data ready to be read or buffer space to be written. This is done in a single thread though, but while the initial code is a bit larger, in the end this approach is easier and cleaner, even more so if multiple streams are involved.
但是,如果您正在一个线程中进行块读,那么另一个线程可能会被阻塞,等待编写一些东西。这可能是一个僵局。一种解决方案是使用select()来检测何时有一些数据准备被读取或要写入缓冲区空间。虽然这是在一个线程中完成的,但是虽然最初的代码有点大,但是最终这种方法更简单、更干净,如果涉及到多个流的话更是如此。