Page 1 of 1

EV3 BCC / Sharing variables between threads

Posted: 25 Oct 2013, 20:40
by holler
As this thread turned into some talk about multi-threading using C/C++, I think
I should make people aware of another problem: sharing variables between threads.

Code: Select all

double d;

void thread_1(void)
{
        ...
        d+=10;
}       

void thread_2(void)
{
        double my_d = d;
        ...
}       
A double is 64bits long on ARM, so the cpu needs (at least) two operations to read or write it.
What now might happen if both threads are running is the following:

Code: Select all

thread_1                thread_2
---------------------------------------------
writes lower part of d  -
-                       reads lower part of d
-                       reads upper part of d
writes upper part of d   -
That's why I've used std::atomic<int> instead of just int in my previous C++11 thread example.

And as a warning: the C standard doesn't guarantee that even operations on native types (like integers) are done as an atomic operation (in one part). You might have luck with such (it depends on the compiler-(version) and some other things), but to be sure you have to use either atomic operations or you need to use mutexes, semaphores or similiar to protect reads and writes on shared variables from simultaneous access. (And don't use plain integers as replacement for a real mutexes.)

Don't forget, the EV3 uses a real operating system and real threads are a lot different than e.g. threads in python, nbc or nxc.

Alexander Holler

Re: EV3 BCC / Sharing variables between threads

Posted: 26 Oct 2013, 08:17
by mightor
split off from the other thread. This is useful info, it shouldn't be deluged by conversation in another unrelated thread.

= Xander

Re: EV3 BCC / Sharing variables between threads

Posted: 26 Oct 2013, 09:15
by pepijndevos
I dug up some example for using mutexes:

Code: Select all

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

pthread_mutex_t mutex;

int number = 0;

void *dostuff(void *arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        number++;
        pthread_mutex_unlock(&mutex);
   }
}

int main(void)
{
    pthread_t tid;
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&tid, NULL, dostuff, NULL);
    dostuff(NULL);
    pthread_join(tid, NULL);
    pthread_mutex_destroy(&mutex);
    return 0;
}
Alternatively you could use a queue for passing messages around, or just don't share state.