多个线程针对一个串口的读写操作的时候,出现线程冲突,求解决方案。

Tidal_Choidi 2018-12-29 09:46:04
写了一个程序,其中的一个线程A一直读串口的数据,将串口设备上的数据显示在界面上。
其中还有两个线程B,C,是对连接到串口上的设备进行读写操作。因为A线程一直在对串口进行读操作,当B或者C再对串口进行写操作的时候就报异常了,请问,类似这样的多线程对同一个串口的操作有什么好的办法?
我上面的思路不清楚有没有问题?
...全文
3648 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
PaulyJiang 2019-08-02
  • 打赏
  • 举报
回复
冲突 就加锁就行了
cbs11403 2019-07-31
  • 打赏
  • 举报
回复
Linux下一个线程负责读,一个线程负责写即使是非重叠IO模式是可以正常工作的,就好像全双工模式;在Win32下面文件句柄只能读写打开,当一个线程在读的时候,这时再用同一个句柄去写Win32程序会因为读操作未返回所以写也会阻塞。程序应该没有死,只是阻塞了,如果是主窗口阻塞了当然就卡主不动了,给人的感觉是死机了。多线程分工操作本省并没有什么问题,如果为了节省线程创建的系统开销让线程循环执行也是可以的,毕竟每次有数据需要读就去创建一个线程读完就销毁,系统会有创建线程和销毁线程的开销。创建好的线程循环等待唤醒就可以了,实际上是可以节省系统开销的。不知道何时线程循环等待就成了死机的根源了。
Tidal_Choidi 2019-01-04
  • 打赏
  • 举报
回复
引用 3 楼 以专业开发人员为伍 的回复:
写数据,直接就写就行了。 在 .net 框架中实现的端口写操作函数,都能安全地在子线程中写数据。你所谓的“进行写操作的时候就报异常了”应该是你的代码由于滥用线程死循环,所以额外地复杂了混乱了一些所谓的控制代码,才出现的异常。原本没有死循环、没有阻塞的异步代码,非常简洁清晰,也不会有这个多问题。这就好像是一堆没有任何学车训练的人胡乱地驾车冲上高速路,把路堵死了,而且事故频出。
================================================================================== 感谢从大的范围上给与指点。
Tidal_Choidi 2019-01-04
  • 打赏
  • 举报
回复
引用 2 楼 xian_wwq 的回复:
[quote=引用 楼主 Tidal_Choidi 的回复:] 写了一个程序,其中的一个线程A一直读串口的数据,将串口设备上的数据显示在界面上。 其中还有两个线程B,C,是对连接到串口上的设备进行读写操作。因为A线程一直在对串口进行读操作,当B或者C再对串口进行写操作的时候就报异常了,请问,类似这样的多线程对同一个串口的操作有什么好的办法? 我上面的思路不清楚有没有问题?
对于串口这类低速设备, 感觉多线程没有多大的施展空间呀 如果要用多线程,那全局变量就需要加锁, 或者把相关操作串行化 没有搞明白,写入为何会是多个线程? [/quote] ===================================== 也尝试着使用lock语句解决问题,只是把lock语句加在了串口操作类里面的Write()和Read()两个方法上,可能是使用错误导致效果不明显。 之所以出现对同一个设备进行串口写操作,原因是:有一个线程一直在循环读设备的值,期间还有一个线程要对该设备进行设置参数的工作,所有出现了两个线程操作同一个串口设备,现在看来,即便使用多线程也是串行的对同一个设备进行读、写命令的操作。
Tidal_Choidi 2019-01-04
  • 打赏
  • 举报
回复
引用 1 楼 以专业开发人员为伍 的回复:
什么叫做“A线程一直对串口进行读操作”? 线程操作只需要几毫秒,异步的。搞一些同步死循环阻塞语句来滥用线程,不死掉才怪。
========================================================== 纠错一下:1.是A线程一直对一个串口循环进行读数据操作。不停的读操作就是为了监控设备输出数据状态。 2.程序/进程并没有死掉,尽管用了一个while循环,但中间有一定的Sleep()时间。
Tidal_Choidi 2019-01-03
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
多个线程针对一个串口的读写操作?这根本就是错误的设计
必然出现不可调和的矛盾!


针对我提出的上面的功能需求,该怎么设计比较合理呢?请指点。
wanghui0380 2019-01-03
  • 打赏
  • 举报
回复
ps:并发和并行应该清楚,不是说性能问题就线程,你的搞清楚,你到底处理的是并行还是并发
wanghui0380 2019-01-03
  • 打赏
  • 举报
回复
串口和文件一样,属于争抢资源

这个需要的是处理并发,而非处理并行。所以多线程不是不可以,但是你要想好他是并发,但是如果他是并发,你想玩就加锁,不过加锁就排序,实际还是“假装他多线程了”

所以这东西,需要反向包装,一个读写,多个共享才是正常方式
xuzuning 2019-01-03
  • 打赏
  • 举报
回复
你可以将串口操作放在一个类中(单例)
通过这个类,串行的处理所有的串口操作需求(类中可能需要一个队列来缓存操作请求)
  • 打赏
  • 举报
回复
如果你操作的是一些早期的单线程 COM 机制的组件,那么自然是要在 UI 主线程去操作。这就要看你具体的操作是早期已经淘汰的“串口”机制还是 .net 框架中新的机制。这些都要贴出真正的调试画面,不能仅凭个别字眼儿。不过从大的编程模式上来说,如果你思路中有“多线程各自死循环”的思路,这本身就是初学者习惯的一条把程序搞死的思路。
  • 打赏
  • 举报
回复
写数据,直接就写就行了。 在 .net 框架中实现的端口写操作函数,都能安全地在子线程中写数据。你所谓的“进行写操作的时候就报异常了”应该是你的代码由于滥用线程死循环,所以额外地复杂了混乱了一些所谓的控制代码,才出现的异常。原本没有死循环、没有阻塞的异步代码,非常简洁清晰,也不会有这个多问题。这就好像是一堆没有任何学车训练的人胡乱地驾车冲上高速路,把路堵死了,而且事故频出。
xian_wwq 2018-12-29
  • 打赏
  • 举报
回复
引用 楼主 Tidal_Choidi 的回复:
写了一个程序,其中的一个线程A一直读串口的数据,将串口设备上的数据显示在界面上。
其中还有两个线程B,C,是对连接到串口上的设备进行读写操作。因为A线程一直在对串口进行读操作,当B或者C再对串口进行写操作的时候就报异常了,请问,类似这样的多线程对同一个串口的操作有什么好的办法?
我上面的思路不清楚有没有问题?

对于串口这类低速设备,
感觉多线程没有多大的施展空间呀
如果要用多线程,那全局变量就需要加锁,
或者把相关操作串行化
没有搞明白,写入为何会是多个线程?





  • 打赏
  • 举报
回复
什么叫做“A线程一直对串口进行读操作”? 线程操作只需要几毫秒,异步的。搞一些同步死循环阻塞语句来滥用线程,不死掉才怪。
xuzuning 2018-12-29
  • 打赏
  • 举报
回复
多个线程针对一个串口的读写操作?这根本就是错误的设计
必然出现不可调和的矛盾!
gd6321374 2018-12-29
  • 打赏
  • 举报
回复

对于串口这个IO进行操作,你多个线程同时操作串口就需要处理好多线程的同步问题。
这个时候需要加锁,
对于A线程一直在读取数据,主要看你读取串口时是同步操作还是异步操作的,
如果是异步读取,可以设置超时时间,然后在循环中,检测标识位B或C线程是否在写入,如果在B或C线程在写入,你就需要暂停等待你的
A线程的串口读取,直到B或C线程写完为止,然后将标识位置为允许读取,这样子A线程检测到允许读取,就可以继续读串口了。


平底锅锅锅 2018-12-29
  • 打赏
  • 举报
回复
用lock试试

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧