问题
I'm trying to communicate with the same port using two different threads in a CLI C++ program (running on Windows but not using the Windows API). The port is a USB port (that leads to a converter to RS-232 and then to another device). I can successfully establish port communications in my main
thread using OpenCom()
and Transmit()
, functions provided in a DLL by the manufacturer of those devices.
I then call newThreadFunc()
(defined in another DLL), which runs in a separate thread (let's call it the callback thread) and calls a callback function. In that callback function, I call Transmit()
again, but now it returns with an error (defined by the DLL): "Port not ready (CreateFile)".
Here is the simplified pseudo-code:
#include "Device.h" // contains OpenCom() & Transmit()
const short comPort = 3; // COM port number (global)
int main(int argc, char* argv[]) {
OpenCom(comPort); // Open the port
Transmit(command); // where "command" represents some command
newThreadFunc(taskHandle); // Creates new "callback thread" and calls callbackFunc
getchar(); // wait while other thread runs
return 0;
}
signed long __cdecl callbackFunc (params) {
Transmit(command); // error: "Port not ready (CreateFile)"
OpenCom(comPort); // error: "Port already open (CreateFile)"
}
If I call OpenCom
in the callback thread, I get this error: "Port already open (CreateFile)". So the callback thread can see that the port is open but cannot communicate on it. I know I should manage the port communications somehow with a mutex or similar, but what's the reason why the callback thread can't communicate on the port? And how can I allow the callback thread to communicate on the port I opened in the main thread?
回答1:
Serial ports are very simple devices, they just support an opaque stream of bytes. There is no protocol to allow two threads or two applications to share a port. Nothing like TCP that allows a logical connection to a specific port number across a single network connection. In the OSI model, a serial port occupies the bottom one, the physical layer. With no standard that ever emerged to build layers on top of it, nobody ever agreed on what layer #2 should look like. The Hayes AT protocol for modems is as far as it ever got.
So if the OS would actually allow you do this then the outcome would be very poor. One app or thread would steal the input meant for another, that can never come to a good end. So you really do have to take care of this yourself and open the port once. With some kind of scheme to arbitrate access to the port that determines which thread gets the input. Like a mutex. Or a network layer you create that has a logical destination address, very common in bus protocols. That can be as simple as a single byte in a message. But of course adding the requirement that you implement the data link layer and specify a message frame format so this byte can reliably be read. Very common as well, everybody spins their own.
来源:https://stackoverflow.com/questions/21525516/how-can-i-allow-thread-2-to-communicate-on-the-port-i-opened-in-thread-1