使用多线程程序来接收和组织串行消息(在MFC/c ++中)

问题描述:

我是编程多线程事物的新手,所以我想知道是否有人可以帮助我.

我必须编写一个程序来接收串行(连续)异步消息,然后阅读并整理此消息.

我正在尝试使用多线程策略:第一个线程负责接收串行信息并将其写入矩阵(RxTh [col] [row]),一次写入一行.然后,调用第二个线程,以读取RxTh矩阵的每一行并搜索特定的字符(表示开始行" msg).该线程还必须将接收到的消息放入另一个矩阵(Msg [col2] [row2])中,该矩阵将味精的每一行分隔在新矩阵的不同行中.

将来,我将不得不处理这些重新排列的行,并搜索特定信息,但是我现在不在考虑这一部分.

因此,我在程序上遇到了一些问题:-首先,当我停止写以开始读取部分时,我丢失了一些串行消息.这就是为什么我尝试使用互斥或​​关键部分的原因.但这不起作用,我也不知道为什么.

-第二个问题是,第二个矩阵(Msg [] [])在某些行的中间具有奇怪的序列"0",并且我怀疑此"0"出现在此线程中开始读取RxTh矩阵的新行.有道理吗?

-使用互斥锁时,一次只能锁定一行吗?

如果有人可以帮助我,我将不胜感激!

如果您需要更多信息或一段代码,请问我!

谢谢

I''m new with programing multithreads things, so I''m wondering if anyone could help me.

I have to make a program that receives a serial (and continuous) asynchronized message, and then read it and organize this message.

I''m trying to use a multithread tactic: the first thread is responsible to receive the serial info and write it in a matrix (RxTh[col][row]), one line at a time. Then, the 2nd thread is called, to read each line of the RxTh matrix and search for specific chars (that symbolizes the ''begin line'' msg). This thread also have to put this received messages in another matrix (Msg[col2][row2]) separating each line of the msg in a different row in the new matrix.

In the future, I''ll have to work with this rearranged lines, and search for specifics information, but I''m not thinking in this part right now.

So, I''m having some problems with this program: -First, I''m losing some pieces of the serial message when I stopped writing to begin the read part. That’s why I''ve tried to use mutex, or critical section. But it isn''t working, and I don’t know why.

-The second problem, is that the second matrix (Msg[][]) has strange sequences of ''0'' in the middle of some lines, and I''m suspecting that this ''0'' appears while this thread starts to read a new row of the RxTh matrix. Does it make any sense?

-When I use mutex, can I lock only one row at a time?

If someone could help me, I''ll appreciate a lot!!

If you need more information or a piece of the code, just ask me!

Thanks

我当时用RS232输入做了很多工作,遇到了一些我没想到会遇到的陷阱.
您未指定使用的是真实" COM端口还是USB COM端口设备. USB COM端口设备很棒,但是它们不能100%用作本机COM端口,并且取决于制造商(大多数设备似乎使用FTDI( www.ftdichip.com )驱动程序),则可能会遇到缓冲区大小和读/写时序问题.

您所描述的"0"字符是我看到的很多东西-通常以四个"0"为一组.您确定它们仅出现在第二个矩阵中吗?您应该检查字符是否实际上是从COM端口读取的以及是否也出现在第一个矩阵中.

Soren Madsen
I have done a lot of work with RS232 input in my time and I have encountered several pitfalls that I did not expect to stumble across.
You are not specifying if you are using a "real" COM port or a USB COM port device. The USB COM port devices are great, but they do not work 100% as a native COM port and depending on the manufacturer (most of them seem to use an FTDI (www.ftdichip.com) driver) you can run into issues with buffer sizes and read/write timing.

The ''0'' characters you describe is something I see quite a bit - usually in groups of four ''0''s. Are you sure they only appear in the second matrix? You should check to see if the characters are in fact read from the COM port and appear in the first matrix as well.

Soren Madsen


我以前发布了有关常规COM端口功能的回复.我想对您的程序结构提出建议.

显然,有许多方法可以进行数据流,但是鉴于您的解释,我建议您进行一些更改,以便从串行端口读取的线程将数据传递给第二个线程,而无需将其写入第一个矩阵. >
要传递数据,我只需分配一个新的字节缓冲区,将数据复制到新缓冲区,然后发布带有指向新缓冲区和字节数的指针的线程消息.当第二个线程接收到此消息时,它可以处理数据,将其写入第一个矩阵(如果您在此更改后确实需要该矩阵),并在标识消息部分之后将其写入第二个矩阵.
第二个线程将负责处理后删除数据.

一些开发人员不喜欢这种方法,他们会认为所有分配和取消分配都是低效的,但是我相信您会在程序中获得更好的流程,并且不必使用互斥体.

Soren Madsen
I previously posted a response regarding general COM port functionality. I would like to make a suggestion regarding your program structure.

There are obviously many ways of doing the data flow, but given your explanation, I would suggest that you change things around so the thread reading from the serial port passes the data to the second thread without writing it to the first matrix.

To pass the data, I would simply allocate a new byte buffer, copy the data to the new buffer and post a thread message with a pointer to the new buffer and the byte count. When the second thread receives this message, it can process the data, writing it to the first matrix (if you actually need that matrix after this change) and to the second matrix after identifying the message parts.
The second thread will be responsible for deleting the data after processing it.

Some developers do not like this approach and will argue that all the allocating and deallocating is inefficient, but I believe you will get a better flow in your program and you do not have to use the mutex.

Soren Madsen


您的问题很笼统,因此答案也有点笼统:
1)使用单独的线程进行接收是正确的(顺便说一句,如果您也必须进行传输,则应在单独的线程中运行)
2)您应该有一个原始"缓冲区来接收需要通过互斥机制进行保护的串行流(不确定为什么需要矩阵,但不必担心),因为接收线程和消息处理器线程都将访问它(听起来您已经意识到这一点)
3)就像我在Soren的帖子中提到的那样,根据我的经验,实现高效操作的最简单,最快的方法可能是:a)获取互斥体,b)将数据从原始接收缓冲区复制到辅助数据库缓冲区和3),然后释放互斥锁.这意味着您的串行接收器线程几乎不会阻塞,并且数据处理器线程可以在辅助缓冲区空闲时对其进行操作.
4)您必须确保处理消息的速度比到达消息的速度快(生产者/消费者问题).鉴于串行通信与可用于处理数据的CPU能力相比非常慢,这几乎绝不是问题.
5)如果您使用C ++编写,则必须在某个时候使用SetCommTimeouts来设置端口-仔细检查并确保您了解COMMTIMEOUTS结构的所有成员,因为它们将产生重大影响,尤其是IntervalTimeout和TimeoutMultiplier.您可能会看到零,因为您的ReadFile超时.
6)最后,调试程序的显而易见的事情是确保以裸露的形式接收正确的数据.在进行任何数据处理之前,应该先确定这一点.
Your question is general hence the answer is a bit general too:
1) Using a separate thread for receive is correct (incidentally, if you had to transmit as well, it should run in a separate thread)
2) You should have a "raw" buffer that receives serial stream (not sure why you need the matrix but never mind that) that needs to be protected via a mutual exclusion mechanism since the receive thread and message processor thread both will access it (sounds like you are aware of this)
3) As it was alluded to in Soren''s posts, from my experience as well, the easiest and fastest way to achieve efficient operation may be to a) grab the mutex, b) copy data from a raw receive buffer to a secondary buffer and 3) then release the mutex. This means your serial receiver thread almost never blocks and your data processor thread can operate on the secondary buffer at its leisure.
4) You have to make sure that you are processing your messages faster than they arrive (producer/consumer issue). It is almost never an issue given serial comms are extremely slow compared to what CPU power you have available to process data.
5) If you are writing in C++, you must be using SetCommTimeouts at some point to setup your port - double check it and make sure you understand all members of COMMTIMEOUTS structure as they will have a substantial impact, in particular IntervalTimeout and TimeoutMultiplier. You may be seeing zeros because your ReadFile times out.
6) And finally, the obvious thing to do to debug your program is to make sure that in its bare form, it is receiving correct data. That should be established before you do any processing of data.