Tuesday, October 29, 2019

One pattern that I use on multi-threaded environment.

As many Unity developer already knows, Unity's logic runs in main thread. When you need network feature in your project you probably use socket or other network library. Of course when you send/receive some packets over the network, you will use non-blocking or asynchronize mechanism.

Normally we use callback or event function and those are called by OS. Ok then you can do whatever you want. Something like this.

void MyReceiveFunction(data)
{
    // ok, I received a data!
    if ( data == 0 )
    {
        foo(0);
    }
    else if ( data == 1001 )
    {
        foo(1001);
    }
    else
    {
        ...
    }
}

The problem is that the function is called on different thread. (which is not mianthread)

so If you do anything that it is related with main thread or GUI, logic won't run correctly. The pattern I'm going to talk about is saving this situation! (very simple)

void MyReceiveFunction(data)
{
    // ok, I received a data!
    if ( data == 0 )
    {
        reserveFoo(0);
    }
    else if ( data == 1001 )
    {
        reserveFoo(1001);
    }
    else
    {
        ...
    } 
}

in the reserveFoo function we can reserve the command like below.

void reserveFoo(int cmd)
{
    lock
    {
        reserveFooList.add(cmd);
    }
}

reserveFooList is a container. It store a cmd. and it is used in consumer logic in mainthread.


// Update function is called in main thread.
void Update()
{
    if ( reserveFooList.size > 0 )
    {
        foreach(element : reserveFooList)
        {
            Foo(element);
        }

        reserveFooList.clear;
    }
}

Now Update function is called in main thread and checks whether size of reserveFooList is greater than 0 which means it has some element to do.

if the list is not empty then iterate all the elements and process those in main thread. That's is the main idea.

Of course you can use invoke method for solve this issue but personally I prefer to do this.

No comments:

Post a Comment

Task in UnrealEngine

 https://www.youtube.com/watch?v=1lBadANnJaw