Global variable synchronization between threads in C
<p>I am developing a robot controlled by Arduino. It will be receiving command from a program on my PC over TCP and forward to Arduino via serial communication. Once Arduino execute the command, it sensors mounting on it will return the environment status to PC. Then program will run some algorithm to decide what action to take next. I am able to receive directional command to move the robot manually from an Android application. I am using Raspberry Pi as the messages passing/control device. </p>

<p>Program on PC, Android application and Arduino sketch are complete and tested. But the communication issue among several threads in the program running on Rpi persists.</p>

<p>So far I have the following (the TCP, serial, bluetooth socket codes are omitted as they are out the scope of this question):</p>

<pre><code>int canForwardToPC, recvFromPC, recvFromAndroid, recvFromAr, canSendCommand, isWaitingForInstruc, isWaitingForPos;

//all the int are initialized to be 0

void *ar_send(){
    int status;

    do{
        if(canSendCommand){
            status = write(ser, output, BUFFER_SIZE);
            if(status != -1) {

                printf("Sent to Arduino: %s\n", output);

                memset(&amp;output[0], 0, sizeof(output));

                isWaitingForGridStr = 1;
                canSendCommand = 0;

                usleep(1000000);

            }else{
                ar_isConnected = 0;
                printf("Error Writing\n");
            }
        }
    }while(1);

}

void *tcp_send(){

    int status;

    do{
        if (canForwardToPC &amp;&amp; tcp_isConnected){
            status = write(newsockfd, output, strlen(output));
            printf("Sent to PC: %s\n", output);
            memset(&amp;output[0], 0, sizeof(output));
            if (status &gt; 0) {

                isWaitingForInstruc = 1;
            }

            else{
                tcp_isConnected = 0;
                usleep(10000000);
            }
            canForwardToPC = 0;
        }
    } while (1);

}

void *bt_recv(){

    int bytes_read;

    do{
        bytes_read = read(client, bt_buffer, sizeof(bt_buffer));
        if(bytes_read &gt; 0) {

            printf("Received \"%s\" from Android\n", bt_buffer);
            recvFromAndroid = 1;

        }
        else{

            bt_isConnected = 0;

        }
    }while(1);

}

void *ar_recv(){

    do{
        if(isWaitingForGridStr){

            n  = read(ser, ar_buffer, BUFFER_SIZE);

            if(n &lt;= 0) continue;

            ar_buffer[BUFFER_SIZE] = '\0';

            printf("Received %s from Arduino.\n", ar_buffer);

            isWaitingForGridStr = 0;

            recvFromAr = 1;

        }
    }while(1);

}

void *tcp_recv(){

    do{
        if (tcp_isConnected &amp;&amp; isWaitingForInstruc){


            n = read(newsockfd, tcp_buffer, BUFFER_SIZE);


            isWaitingForInstruc = 0;

            printf("Received %s from PC.\n", tcp_buffer);
            if (n &gt; 0){
                recvFromPC = 1;

            }else{
                tcp_isConnected = 0;
                usleep(10000000);
            }
        }
    } while (1);

}

void *controller(){
do{
    if(recvFromAndroid){

        recvFromAndroid = 0;



        char temp[1];
        temp[0] = bt_buffer[0];

        canForwardToPC = 1;

        strncpy(output, temp, sizeof(temp));
        memset(&amp;bt_buffer[0], 0, sizeof(bt_buffer));


    }

    else if(recvFromAr){

        recvFromAr = 0;


        canForwardToPC = 1;

        isWaitingForInstruc = 1;]

        strncpy(output, ar_buffer, sizeof(ar_buffer));
        memset(&amp;ar_buffer[0], 0, sizeof(ar_buffer));

    }

    else if(recvFromPC){

        recvFromPC = 0;

        canSendCommand = 1;

        strncpy(output, tcp_buffer, sizeof(tcp_buffer));
        memset(&amp;tcp_buffer[0], 0, sizeof(tcp_buffer));

    }

    }while(1);

}
</code></pre>

<p>Each method is one thread and will be created and joined in the main function.</p>

<p>From what I see, output are well protected by all the integers and the receive and send threads are organize properly. The code seems legit.</p>

<p>But I have the following partial output which is not as planned:</p>

<pre><code>Sent to PC: W1
Received W1 from PC.
Sent to Arduino: W1
Received 0:0:0:2:0:3 from Arduino.
Sent to PC: 0:0:0:2:0:3
Received W1W1W1W1W1D180W1A180W1 from PC.
Sent to Arduino: W1W1W1W1W1D180W1A180W1
Received -1:0:-1:2:0:3 from Arduino.
Received W1D180W1A180W1W1W1W1A180 from PC.
Sent to PC: -1:0:-1:2:0:3
Received W1 from PC.
Sent to Arduino: W1
Received -1:-1:-1:-1:0:3 from Arduino.
Received W1D180W1D180W1W1W1A180W1 from PC.
Sent to PC: -1:-1:-1:-1:0:3
Received W1 from PC.
Sent to Arduino: W1
Received -1:-1:-1:-1:0:3 from Arduino.
Received D180W1W1W1W1W1W1D180W1 from PC.
Sent to PC: D180W1W1W1W1W1W1D180W1
Received A180 from PC.
Sent to Arduino: A180
Received -1:-1:-1:1:0:3 from Arduino.
Sent to PC: -1:-1:-1:1:0:3
Received W1W1W1D180W1W1W1W1 from PC.
Received W1 from PC.
</code></pre>

<p>The only thing I want to send to PC is the position string, which is in the form x:x:x:x:x:x. But there is an instance where D180W1W1W1W1W1W1D180W1 is sent to PC.</p>

<p>The expected output should be repeatedly as the following:
Send to PC
Receive from PC
Send to Arduino
Receive from Arduino</p>

<p>I suspect that there occur some global variable inconsistency that caused the unexpected output. </p>

<p>I have found severals articles about semaphore and mutex but those are solutions for 2 threads only. I have 6 threads running here and I have no idea how to implement semaphore.</p>

<p>What can I do to resolve the data inconsistency problem?</p>

<p>Any help will be appreciated.</p>