Re: Setting a global variable into a thread



On 08/12/10 14:08, Pavel Vasilyev wrote:
On 08.12.2010 12:55, David Brown wrote:
On 07/12/2010 21:26, Pavel Vasilyev wrote:
On 07.12.2010 23:22, Pavel Vasilyev wrote:
On 07.12.2010 21:28, Bogdan wrote:
Hi
I have a global variable (my_var) initialized to zero and from the
main thread another thread is created which only sets the global
variable to one. After creating the secondary thread, the main thread
waits for the global variable to be set to one like this:

while (0 == my_var);

Even if the global variable is set in the secondary thread, the main
thread remains blocked forever in the while loop. If I use instead:

while (0 == my_var)
{
sleep(1);
}

the main thread detects that the global variable has been set. Could
someone explain what happens in the first case and why the global
variable is not detected when it is set ?


Ooops

int local_var = 0;

while (0 == local_var)
{
sleep(1);

write_block(my_var);
local_var = my_var;
write_unblock(my_var);
}

The same is true in other places where you use this variable.

What's in your "write_block" and "write_unblock" functions/macros?
Just example.


And how is this better than making my_var volatile?
Not work.


My experience with this sort of thing is mostly with small microcontrollers, rather than Linux - most of my Linux programming is in Python rather than C, which handles this sort of thing differently.

Can you tell me /why/ this would not work:

static volatile int my_var;

void threadOne(void) {
while (0 == my_var) ;
doSomething();
}

void threadTwo(void) {
doSomething();
my_var = 1;
doSomething();
}


Obviously the first thread will busy-wait in the while loop, which is seldom a good idea. But as long as priorities and/or SMP allow threadTwo to run, it will work.

mvh.,

David




There are times when rtos-style locking and synchronisation tools are
important, and times when they are way over-kill. If he wanted an rtos
solution, my_var would be a semaphore.


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#include<stdarg.h>
#include<pthread.h>

sem_t a, b;
int global = 10;


void *one(void *arg __attribute__((unused))) {

int local;

do {
sem_wait(&b);
local = global--;
printf("A = %d\n", local);
sem_post(&a);
} while (local> 0);

pthread_exit(NULL);
}

void *two(void *arg __attribute__((unused))) {

int local;

do {
sem_wait(&a);
local = global--;
printf("B = %d\n",local);
sem_post(&b);
} while (local> 0);

pthread_exit(NULL);
}

int main(void) {

pthread_t pth[2];
pthread_attr_t pattr;

pthread_attr_init(&pattr);
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);

sem_init(&a, 0, 0);
sem_init(&b, 0, 1);

pthread_create(&pth[0],&pattr,&one, NULL);
pthread_create(&pth[1],&pattr,&two, NULL);

pthread_detach(pth[0]);
pthread_detach(pth[1]);

sem_destroy (&a);
sem_destroy (&b);

return 0;
}

.