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

时间:2022-12-17 11:48:05

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:

这有两个方面:

  1. What the C implementation does.
  2. C实现的作用。
  3. What the kernel does.
  4. 什么内核。

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:

这有两个方面:

  1. What the C implementation does.
  2. C实现的作用。
  3. What the kernel does.
  4. 什么内核。

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()来检测何时有一些数据准备被读取或要写入缓冲区空间。虽然这是在一个线程中完成的,但是虽然最初的代码有点大,但是最终这种方法更简单、更干净,如果涉及到多个流的话更是如此。