x number of threads sending data to Server for displaying output on GUI - c

I have developed a single server/multiple client TCP Application.
The client consists of x number of threads each thread doing processing on its own data and then sending the data over TCP socket to the Server for displaying.
The Server is basically a GUI having a window. Server receves data from the client and displays it.
Now, the problem is that since there are 40 threads inside the client and each thread wants to send data, how can I achieve this using one connected socket?
My Suggestion:
My approach was to create a data structure inside each of the 40 threads in which data to be sent will be maintained. A separate Send Thread with one connected socket on client side is then created. This thread will read data from data structure of first thread, send it over the socket and then read the data from second thread and so on.
Confusions:
but I am not sure how would this be implemented as I am new to all this? :( What if a thread is writing to data structure and the Send Thread tries to read the data at the same time. I am familiar with mutex, critical section etc but that sounds too complex for my simple application.
Any other suggestions/comments other than my own suggestion are welcome.
If you think my own approach is correct then please help me solving my confusions that I mentioned above.
Thanks a lot in advance :)
Edit:
Can I put I timer on Send Thread and after a specific time the Send Thread suspends thread#1(so that it can access its data structure without any synchronization issues), reads data from its data structure, sends it over the tcp Socket, and resumes Thread#1 back, then it suspends Thread#2, reads data from its data structure, sends it over the tcp Socket, and resumes Thread#2 back and so on.

A common approach is to have one thread dedicated to sending the data. The other threads post their data into a shared container (list, deque, etc) and signal the sender thread that data is available. The sender then wakes up and processes whatever data is available.
EDIT:
The gist of it is as follows:
HANDLE data_available_event; // manual reset event; set when queue has data, clear when queue is empty
CRITICAL_SECTION cs; // protect access to data queue
std::deque<std::string> data_to_send;
WorkerThread()
{
while(do_work)
{
std::string data = generate_data()
EnterCriticalSection(&cs);
data_to_send.push_back(data);
SetEvent(data_available_event); // signal sender thread that data is available
LeaveCriticalSection(&cs);
}
}
SenderThread()
{
while(do_work)
{
WaitForSingleObject(data_available_event);
EnterCriticalSection(&cs);
std::string data = data_to_send.front();
data_to_send.pop_front();
if(data_to_send.empty())
{
ResetEvent(data_available_event); // queue is empty; reset event and wait until more data is available
}
LeaveCriticalSection(&cs);
send_data(data);
}
}
This is of course assuming the data can be sent in any order. I use strings only for illustrative purposes; you probably want some kind of custom object that knows how to serialize the data it holds.

Suspending thread#1 so you can access its data strcuture does not avoid synchronization issues. When you suspend it thread#1 could be in the midst of an update to the data, so the socket thread gets part of old data, part of new. That is data corruption.
You need a shared data structure such as a FIFO queue. The worker threads add to the queue, the socket thread removes the oldest item from the queue. All access to this shared queue must be protected with a critical section unless you implement a lock-free queue. (A circular buffer.)
Depending on your application needs, if you implement this queue you might not need the socket thread at all. Just do the dequeueing in the display thread.

There are a couple of ways to achieving it; Luke's idea suffers from race conditions that will still create data corruption
You avoid that by using UDP instead of TCP as the transport protocol. It'd be especially a good choice if you don't mind missing an occasional packet (which is okay for displaying rapidly changing data); it's fantastic for ensuring real-time updates on data where exact history doesn't matter (missing a point in a relatively smooth curve while plotting graphs is okay);
If the data packets are are small and sort of represent a stream then UDP is a great choice. Its benefit increases if you have multiple senders on different systems all displaying on a single screen.

Related

libuv combines mutliple async calls and invokes callback once

Requirement : A UDP server that on receiving an UDP packet and stores the received packet to one of the two queues. A worker thread is associated with each queue, and the associated thread picks up packet from the front of the queue, processes it and writes it into a in-memory cache system.
Constraints : solution has to be based on event-loop(libuv) and written in C
My Solution
register a call-back for incoming UDP which adds the received packet to one of the two queues and raises a uv_async_send
two global uv_sync_t objects are created one for each queue and used as parameter for uv_async_send. For ex : if packet is added to queue-one then uv_sync_t object-1 is used as parameter for uv_async_send. Similarly, if packet is added to queue-two then uv_sync_t object-2 is used
two threads are started, each having their own loop and a handle bound with a callback
In thread-one uv_sync_t object-1 is bound against a function (say funcA).
In thread-two uv_sync_t object-2 is bound against another function (say funcB)
funcA and funcB reads "SINGLE" packet from corresponding queue and stores it in the in-memory cache
The problem
The Client sends large number of packets which registers large number of events in the server. Now the problem is that libuv combines multiple calls into one and invokes a single callback(which removes a SINGLE node from queue). This leads to situation where nodes are being added to the queue at a faster rate and removed at a very slow rate. Can these rates be balanced ?
Is there a better way to design the server using event-looping library libuv ?
Since you are queueing the packets in one thread but processing in another, it's possible that they work at slightly different rates. I'd use a thread-safe queue (have a look at concurrencykit.org) and process the entire queue on the async callback, instead of just processing a single packet.

win32: Reading message queue

I need to read the thread message queue, but I cannot use the traditional GetMessage-in-a-loop approach since this thread already handles other data sources via WaitForMultipleObjects. Is there a way to add the thread message queue as an additional event source for WaitForMultipleObjects?
You are looking for MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx.

Camel need Non-blocking Queue - Analogous to not processing events on graphics thread

Sorry I answered my own question - it actually IS just SEDA, I assumed when I saw 'BlockingQueue' that SEDA would block until the queue had been read ... which of course is nonsense. SEDA is completely all I need. Question answered
I've got a problem that's compeletely screwing me, I've been provided a custom Endpoint by company we connect to, but the endpoint maintains a heart-beat to a feed, and when it sends messages above a certain size they take so long to process on the route that its blocking and the heartbeat gets lost and the connection goes down
Obviously this is analogous to processing events on a non-graphics thread to keep a smooth operation going. But I'm unsure how I'd achieve this in camel. Essentially I want to queue the results and have them on a separate thread.
from( "custom:endpoint" )
.process( MyProcesor )
.to( "some-endpoint")
as suggested camel-seda is a simple way to perform async/mult-threaded processing, beware that the blocking queues are in-memory only (lost if VM is stopped, etc). if you need guaranteed messaging support, use camel-jms

Multithreaded c program design help

I don't have much experience with multithreading and I'm writing a c program which I believe is suited to running in two threads. The program will listen on the serial port for data, read and process new data when it's available, and publish the newest processed data to other (irrelevant) modules via a third party IPC api (it's confusingly named IPC) when requested.
In order to receive the request to publish data via IPC, the program must call IPC_listenwait(wait_time);. Then if a request to publish is received while "listenwaiting" a handler is invoked to publish the newest data.
One option is to do this in one thread like:
for(;;) {
read_serial(inputBuffer);
process_data(inputBuffer, processedData); //Process and store
IPC_listenwait(wait_time); //If a request to publish is received during this,
} //then a handler will be invoked and the newest piece of
//processedData will be published to other modules
publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
IPC_publish(newest(processedData));
}
And this works, but for the application it is important that the program is very responsive to the request to publish new data, and that the data published is the newest available. These goals are not satisfied with the above because data may arrive after the process begins listenwaiting and before a request to publish message is received. Or the process may be reading/processing when a request to publish message is incoming, but won't be able to service it until the next IPC_listenwait call.
The only design I can think of is to have one thread to read, which will just do something like:
readThread() {
for(;;) { //pseudocode
select();
read(inputBuffer);
process(inputBuffer, processedData);
}
}
And have the main thread just listening for incoming messages:
mainThread() {
IPC_listenwait(forever);
}
publishRequestHandler() { //Invoked when a message is received during IPC_listenwait
IPC_publish(newest(processedData));
}
Is this the design you would use? If so, will I need to use a semaphore when accessing or writing processedData?
Will this give me good responsiveness?
Thanks
You're mostly on the right track.
The one thing you have to watch out for is concurrent access to the publishable data, because you don't want one thread clobbering it while another is trying to read it. To prevent that, use a pair of buffers and a mutex-protected pointer to whichever one is considered current. When process_data() has something ready, it should dump its results in the non-current buffer, lock the pointer mutex, repoint the pointer to the buffer containing the new data and then release the mutex. Similarly, the publisher should lock the pointer mutex while it reads the current data, which will force anything that might want to clobber it to wait. This is a bit more complex than having a single, mutex-protected buffer but will assure that you always have something current to publish while new data is being prepared.
If your processing step takes long enough that you could get multiple sets of data to read, you might split the read/process thread into two and let the reader make sure the processor only ever gets the latest and greatest so you don't end up processing stuff you won't ever publish.
Excellent first question, by the way. Have an upvote.

Is Socket.SendAsync thread safe effectively?

I was fiddling with Silverlight's TCP communication and I was forced to use the System.Net.Sockets.Socket class which, on the Silverlight runtime has only asynchronous methods.
I was wondering what happens if two threads call SendAsync on a Socket instance in a very short time one from the other?
My single worry is to not have intermixed bytes going through the TCP channel.
Being an asynchronous method I suppose the message gets placed in a queue from which a single thread dequeues so no such things will happen (intermixing content of the message on the wire).
But I am not sure and the MSDN does not state anything in the method's description. Is anyone sure of this?
EDIT1 : No, locking on an object before calling SendAsync such as :
lock(this._syncObj)
{
this._socket.SendAsync(arguments);
}
will not help since this serializes the requests to send data not the data actually sent.
In order to call the SendAsync you need first to have called ConnectAsync with an instance of SocketAsyncEventArgs. Its the instance of SocketAsyncEventArgs which represents the connection between the client and server. Calling SendAsync with the same instance of SocketAsyncEventArgs that has just been used for an outstanding call to SendAsync will result in an exception.
It is possible to make multiple outstanding calls to SendAsync of the same Socket object but only using different instances of SocketAsyncEventArgs. For example (in a parallel universe where this might be necessay) you could be making multiple HTTP posts to the same server at the same time but on different connections. This is perfectly acceptable and normal neither client nor server will get confused about which packet is which.

Resources