Confusion should I use Thread Pool?


#1

Hi Jules,

I’m trying to make a Hyper terminal kind of application with juce which continuously reads serial port at high baud rates (115200) in windowsxp,
difference being instead of displaying the data on the console I’m logging it in an xml file also updating some openGl components.

Also I have to send some data to the serial port (as serial port being full duplex) without blocking the read but the data to be sent would be
at very low frequency say 0.2 Hz.

I started using juce thread for each of the jobs:

  1. Read serial port and write in Queue,
  2. Read Queue and update Xml,
  3. Read Queue and update openGL components,
  4. Write Serial port

and now there are so many threads that the system nearly hangs, when I do all these together. I’m quite new to threads so I think I’m unable to
synchronize them properly. I was just confused whether i should use threadpool parent class and have all these threads as pool jobs, will this
class would do the necessary synchronization for my application.

Any help would be great!
Thanks in advance.


#2

I think what you’re looking for is called overlapped IO.
Thread won’t do it, as they’ll all block on the Serial file handle.
I don’t know for Juce’s support of overlapped IO, but it’s probably handled somewhere.


#3

The library doesn’t provide anything for overlapped IO at the moment, I’m afraid.

You could certainly do this using normal IO and threads, but would have to be smart about it. If you’ve got so many threads that the system hangs, then your design has certainly gone very wrong somewhere! Your 4 tasks sound like reasonable things to have 4 threads doing, but your main problem is to make sure that they communicate with each other in a robust and thread-safe way.


#4

Well have you written any code for serial communication or USB communication in juce?

X-Ryl669 I’m aware of Non overlapped and overlapped IO I’m currently exploring and experimenting
with that… its not been documented very well, and quite an old technology too…

Jules the code that Ive written is as under could you see and find out the mistake that I might be doing:


/** Serial reader and queue writer thread  */
class SerialPortReaderQueueWriter :  public juce::Thread
{
public:
	SerialPortReaderQueueWriter ( PayloadQueue*	pPayloadQueue, SerialPort* pSerialPort  ) ;
	~SerialPortReaderQueueWriter  ( ) ;
	
	void run()
        { 
            //1. Read the serial port with crc checks to identify proper packet.
            //2. Push the data packet in a  race safe queue.(this queue is shared between threads but I've coded in a way that until  there is some data in the queue 
            //    the reader would not do anything similarly if the queue is full then the writer would not do any thing )
        };
        

private:
	PayloadData*	_pDataToBePushed ;
        
        /** Windows serial port APIs */
	SerialPort*        _pSerialPort;
	
	/** Shared queue which is allocated in the parent class and the pointer is passed in the constructor */
	PayloadQueue*	_pPayloadQueue;
}


/** Queue reader and xml writer thread  */
class QueueReader : public juce::Thread
{
public:
	QueueReader( PayloadQueue*	pPayloadQueue );
	~QueueReader();	

	void run()
        {
            //1. Read the queue
            //2. Update the xml
            //3. Update the GL component
         };

	void UpdateXml();

	void UpdateOpenGlComponents();
private:

	/** Shared queue which is allocated in the parent class and the pointer is passed in the constructor */
	PayloadQueue*	_pPayloadQueue;
	

	OpenGlInfoComponent*	_canvas1 ;
	juce::XmlElement*	_XmlFile ;
};	


class SerialWriter : public juce::Thread
{
public:
  
	SerialWriter ( SerialPort* pSerialPort  );
	~SerialWriter ();

	void run();	//1. Uploads the command word
	void upLoadCommand(PayloadData sPayload);

private:	
	
	char                  _dataBuffer[256];
	unsigned int      _dataBufferLength;
	unsigned long	_numofbytes;
	SerialPort*         _pSerialPort ;
};
 

All these threads are allocated in a parent class and where the queue and serial port is allocated.
And also when I close the window in the the code points to the file juce thread:

// very bad karma if this point is reached, as
// there are bound to be locks and events left in
// silly states when a thread is killed by force…

I’m calling the stopThread (5000) in the destructors of each of the threads so kind of confused with that as well.


#5

Sorry, haven’t time to offer in-depth help. Use your debugger and watch what’s going on!

To stop correctly, all threads need to regularly check threadShouldExit() to see whether it’s time for them to stop, and if so, they should cleanly return from their run() method.


#6

Aah I was able to come cleanly out of threads. Still working on the overlapped IO, got some inroads still on it.
Thanks.


#7

Hi, we are working on a cross platform software platform and need to be able to have a device like the Raspberry Pi communicate with an Arduino Alamode board from our program writtten usng JUCE.  It would be great if a relatively standard way for our program to run on Windows, Mac and Linux talking to real and virtual comm ports and enumerate them reasonably.

If anyone has something working that does some or all of this, I'd like to chat and possibly buy the source code for that function, instead of slogging through that fun puzzle myself.  If there is open source that does this well with modern JUCE, I haven't been able to find it on the WEB or this site, everything looks quite old.

Thanks for any suggestions, etc.