Does anyone have any idea how to setup multithreading in Urho?
I have a application class(like the samples) that has a subclass(which is the application.). In the subclass I run a logiccomponent that gets a getline. It calls a event. Custom event that a handler in the application subclass has. It runs functions and code there.
I probably subclass in a derived class to keep everything neat.
There needs to be two threads. The main code and then the component-serverconsoleinterface needs to be in a separate thread. So, there is no conflicts.
Do anyone have any suggestion? The documentation on threads seems vague to me. Later on I want to add Telnet access to.
I recommend using the WorkQueue & tasks only for short tasks that need to repeat from frame to frame and benefit from multicore scaling. Something like reading console input sounds like a job for the Thread class, which represents a long-lived thread and is fairly simple to use. Search “public Thread” from Urho code to see where it’s being subclassed & used.
However, for this exact task the ProcessUtils.h also includes a non-blocking console read function, GetConsoleInput(), which you should be able to use in the main thread, so if it works well for you you shouldn’t need to even create a thread.
[quote=“cadaver”]I recommend using the WorkQueue & tasks only for short tasks that need to repeat from frame to frame and benefit from multicore scaling. Something like reading console input sounds like a job for the Thread class, which represents a long-lived thread and is fairly simple to use. Search “public Thread” from Urho code to see where it’s being subclassed & used.
However, for this exact task the ProcessUtils.h also includes a non-blocking console read function, GetConsoleInput(), which you should be able to use in the main thread, so if it works well for you you shouldn’t need to even create a thread.[/quote]
Yea. I found the code.
[code]String GetConsoleInput()
{
String ret; #ifdef URHO3D_TESTING
// When we are running automated tests, reading the console may block. Just return empty in that case
return ret; #endif
#ifdef WIN32
HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
if (input == INVALID_HANDLE_VALUE || output == INVALID_HANDLE_VALUE)
return ret;
// Use char-based input
SetConsoleMode(input, ENABLE_PROCESSED_INPUT);
INPUT_RECORD record;
DWORD events = 0;
DWORD readEvents = 0;
if (!GetNumberOfConsoleInputEvents(input, &events))
return ret;
while (events--)
{
ReadConsoleInputW(input, &record, 1, &readEvents);
if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
{
unsigned c = record.Event.KeyEvent.uChar.UnicodeChar;
if (c)
{
if (c == '\b')
{
PrintUnicode("\b \b");
int length = currentLine.LengthUTF8();
if (length)
currentLine = currentLine.SubstringUTF8(0, length - 1);
}
else if (c == '\r')
{
PrintUnicode("\n");
ret = currentLine;
currentLine.Clear();
return ret;
}
else
{
// We have disabled echo, so echo manually
wchar_t out = c;
DWORD charsWritten;
WriteConsoleW(output, &out, 1, &charsWritten, 0);
currentLine.AppendUTF8(c);
}
}
}
}
#elif !defined(ANDROID) && !defined(IOS)
int flags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
for (;;)
{
int ch = fgetc(stdin);
if (ch >= 0 && ch != '\n')
ret += (char)ch;
else
break;
}
#endif
return ret;
[quote=“cadaver”]I recommend using the WorkQueue & tasks only for short tasks that need to repeat from frame to frame and benefit from multicore scaling. Something like reading console input sounds like a job for the Thread class, which represents a long-lived thread and is fairly simple to use. Search “public Thread” from Urho code to see where it’s being subclassed & used.
However, for this exact task the ProcessUtils.h also includes a non-blocking console read function, GetConsoleInput(), which you should be able to use in the main thread, so if it works well for you you shouldn’t need to even create a thread.[/quote]
I have to look at the class. I’m trying to figure it out. It should be something simple. Although to me it looks extremely vague.
I am sorry if I have confused you further. Note that I was referring to “process” and “thread” in their general context. I was not referring to Urho3D::Thread class in particular. And I said “sounds like” only because I don’t know for sure your actual use case. A process can have many threads, it can run an instance of your app separate from the other. On the server side programming, you usually hear people fork a process from the main process. All I want to say is, determine first what you need.
I was thinking the method would be start the program application class as normal and assign it as the main thread. Then start the servercontrolcomponent in another thread or child.
I am looking at Thread.h and Thread.cpp which I think I would have to use but I’m not certain how.
Enter Command >> quit
Enter Command >> [Tue Jul 28 00:41:59 2015] ERROR: Sending events is only supported from the main thread
quit
Enter Command >> [Tue Jul 28 00:42:01 2015] ERROR: Sending events is only supported from the main thread
t
Enter Command >> [Tue Jul 28 00:42:03 2015] ERROR: Sending events is only supported from the main thread
Error. Invalid command
Enter Command >>
Error. Invalid command
Enter Command >>
[/code]
Why can’t sub threads can’t send events? Or can I force it to.
[quote=“cadaver”]I recommend using the WorkQueue & tasks only for short tasks that need to repeat from frame to frame and benefit from multicore scaling. Something like reading console input sounds like a job for the Thread class, which represents a long-lived thread and is fairly simple to use. Search “public Thread” from Urho code to see where it’s being subclassed & used.
However, for this exact task the ProcessUtils.h also includes a non-blocking console read function, GetConsoleInput(), which you should be able to use in the main thread, so if it works well for you you shouldn’t need to even create a thread.[/quote]
I used that code and it seems to work the only problem I have is when nothing is entered just “return”. it returns 0 basically a empty string.
So, with the function itself I can’t determine when a line is entered with just a return key. It’s not a breaking thing. Just would be a nuisance.