Click to See Complete Forum and Search --> : Sending message to 10 machines simultaneously [Help !]


tomprout
December 29th, 2004, 11:34 AM
Hello !

I need to send a message using TCP/IP to 10 machines simultaneously.
I have made 10 threads like this :

//Wait for synchro event to send message
while (WaitForSingleObject(m_hEventSendSimulMsg, 0) == WAIT_TIMEOUT)
{
Sleep(1);
}
MySendMessage(MachineNumber, MyMsg);//Send message to machine number MachineNumber
long lTime = timeGetTime();
TRACE("Send message to machine %d at ref time = %d\n", MachineNumber, lTime);//Display time at which I sent message

When looking in my debug window I see that messages are not sent exactly at the same time and sometimes there 1 second of difference between two machines...

Can anyone tell me how to send simultaneously 1 message to X machines ???

Thanks in advance...

NoHero
December 29th, 2004, 12:11 PM
There is a little design mistake in your application: What if the object get signaled when one of the thread is handlign 'Sleep(1)'? It will cause a delay so this one would be better:


// Wait infinite for the object to be signaled, so you do not need any sleep
// This waiting will also need no cpu time
if ( WaitForSingleObject(m_hEventSendSimulMsg, INFINITE) == WAIT_OBJECT_0 )
{ // Object got signaled so ...
// Send your message here
}


But if you need the time out you should remove the 'Sleep(1)'. Another problem can be the scheduler: If some of the threads have a lower priority than others then they are might not be scheduled back-to-back. So you should put the threads on an higher priority level than your main thread.

NoHero
December 29th, 2004, 12:16 PM
P.s.: Since the socket subsystem needs time to send and/or the scheduler might has another aims that let your threads sending back-to-back, you cannot aim ten sending operations to occur at one time. You can only minimize the time between them.

tomprout
December 29th, 2004, 12:16 PM
Even if I remove this line I still have big errors... :cry:

In fact I need to send the message to 10 machine in less than 40 ms.

If I try to send to 4 machine, I am under 40ms but if I use 10 machines I get error like message sent to machine_3 1 500ms after sending message to machine_8...

NoHero
December 29th, 2004, 12:18 PM
Even if I remove this line I still have big errors... :cry:

In fact I need to send the message to 10 machine in less than 40 ms.

If I try to send to 4 machine, I am under 40ms but if I use 10 machines I get error like message sent to machine_3 1 500ms after sending message to machine_8...

of course you have: The network subsystem and/or the scheduler will interrupt the threads during the sending. And this will lead to an delay. The only - of course dangerous way - to handle this is to set the threads priorities to THREAD_PRIORITY_TIME_CRITICAL.

tomprout
December 29th, 2004, 12:20 PM
That's I want : Minimize at maximum the time between sending message to machine_1, machine_2, machine_3 ...

If I read log file for example I have :

Ok with 4 machines :


Message to machine_1 sent at 00:00:00:310 (HH:MM:SS:MS)
Message to machine_2 sent at 00:00:00:310 (HH:MM:SS:MS)
Message to machine_3 sent at 00:00:00:310 (HH:MM:SS:MS)
Message to machine_4 sent at 00:00:00:315 (HH:MM:SS:MS)



Problem with 10 machines:

Message to machine_1 sent at 00:00:00:300 (HH:MM:SS:MS)
Message to machine_2 sent at 00:00:00:300 (HH:MM:SS:MS)
Message to machine_3 sent at 00:00:00:300 (HH:MM:SS:MS)
Message to machine_4 sent at 00:00:00:305 (HH:MM:SS:MS)
Message to machine_5 sent at 00:00:00:312 (HH:MM:SS:MS)
Message to machine_6 sent at 00:00:00:900(HH:MM:SS:MS)
Message to machine_7 sent at 00:00:01:010 (HH:MM:SS:MS)
Message to machine_8 sent at 00:00:00:320 (HH:MM:SS:MS)
Message to machine_9 sent at 00:00:00:300 (HH:MM:SS:MS)
Message to machine_10 sent at 00:00:00:300 (HH:MM:SS:MS)

NoHero
December 29th, 2004, 12:27 PM
Yes this caused because the scheduler interrupts your threads and puts others between your's executing. Try to use what I said above: Use SetThreadPriority() and bring your threads to an higher priority level and/or increase the priority of your whole application.

tomprout
December 29th, 2004, 12:33 PM
Yes this caused because the scheduler interrupts your threads and puts others between your's executing I think it is a good explanation

But I already used high level priority adn does not solve my problem...

NoHero
December 29th, 2004, 12:48 PM
Do not use high level use the highest (realtime and time critical) only during the send. And reset to a lower priority after the send has been made. And remember: The network is slow, so you must calculate some more time in then writing to a hard disk or so. Do not forget to change the priority of your process, because only setting an higher priority to your threads means that this threads won't be interrupted to execute other threads of your applicitation. So the main thread. So you also need to change the process priority to the highest level.

tomprout
December 30th, 2004, 05:38 AM
If I do in my main application (Not using thread)

for (int i = 0; i < 10; i++)
{
MySendMessage(Machine[i], MyMsg);
TRACE("Msg sent to Machine %d at %d\n", i, timeGetTime());
}

It seems that all messages are sent at the same time

But if I use ten threads like this one

Thread_Machine0()
{
MySendMessage(Machine[0], MyMsg);
TRACE("Msg sent to Machine 0 at %d\n", timeGetTime());
}

Thread_Machine1()
{
MySendMessage(Machine[1], MyMsg);
TRACE("Msg sent to Machine 1 at %d\n", timeGetTime());
}

.
.
.
.
.

I get time errors even if I use SetThreadPriority with parameter REALTIME_PRIORITY_CLASS

Any idea ?

Andreas Masur
December 30th, 2004, 06:31 AM
Well...note that 10 threads do not help much while working on a single-CPU system anyway...there will always be only one thread that gets the CPU time.

However...how does the sending code look like? Furthermore, what operating system do you use? Your 'Sleep(1)' call will actually sleep way longer than 1 millisecond since it is dependent on the resolution of the operating system which for example is 55ms on a Windows 9x machine.

I also do not see the reason why you did your own 'while' loop for waiting on the event? Simply wait infinite for the event to become signaled as being pointed out...

tomprout
December 30th, 2004, 06:36 AM
I am working on XP Pro...

When I do SetEvent(m_hEventSendSimulMsg) the message should be sent to 10 machines...

Mathew Joy
December 30th, 2004, 01:21 PM
Let me give some suggestions.

You need to redesign your app such that at the point of signaling m_hEventSendSimulMsg all of your threads must be in a wait state..waiting for an object to signal.

You shouldn't poll, especially with Sleep(1) as being pointed out. Sleep(0) is better since it forces a context switch. As suggested previously, the best is to waint 'INFINITE'ly.

Third is as soon as the event is signaled, send() and either Sleep(0) or wait again till all the threads complete sending.

Finally, check the time taken at the client machine, not at the server side. Obviously if the client is not able to get it in time, there is no point in send it faster. If that is not possible, take the time and only print it after the send() is completed.

You can experiment with changing the priority class (I think 1 or 2 points above is enough) as suggested, though I don't think it is absolutely necessary.

With this I guess you can come close, but whether you can reach the above figure depends on other factors.

tomprout
January 3rd, 2005, 01:58 AM
Ok thanks will check my code...