I make no pretence at elegance, but this seems to work for me on MacOS X 10.5.8.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void *writer(void *arg)
{
int * volatile i = arg;
for (*i = 1; *i < 10; (*i)++)
{
printf("writer(): pseudo_global = %d\n", *i);
fflush(stdout);
sleep(1);
}
printf("writer(): pseudo_global = %d (exiting)\n", *i);
fflush(stdout);
return(0);
}
static void *reader(void *arg)
{
int * volatile i = arg;
while (*i < 10)
{
printf("reader(): pseudo_global = %d\n", *i);
fflush(stdout);
sleep(1);
}
printf("reader(): pseudo_global = %d (exiting)\n", *i);
fflush(stdout);
exit(0);
}
int main(void)
{
volatile int pseudo_global = 0;
pthread_t t1;
pthread_t t2;
if (pthread_create(&t1, 0, writer, &pseudo_global) != 0)
{
perror("pthread_create() for thread 1");
exit(1);
}
if (pthread_create(&t2, 0, reader, &pseudo_global) != 0)
{
perror("pthread_create() for thread 1");
exit(1);
}
while (pseudo_global < 10)
{
printf("main(): pseudo_global = %d\n", pseudo_global);
fflush(stdout);
sleep(1);
}
printf("main(): pseudo_global = %d (exiting)\n", pseudo_global);
fflush(stdout);
return(0);
}
Note that I put the 'volatile' qualifier into the code to 'make sure', but apart from eliciting warnings about discarded qualifiers in the calls to pthread_create()
, it didn't make any significant difference. I also ran the code without any volatile
qualifiers without problem.
This code demonstrates, I think, that on at least one POSIX threads implementation, you can indeed share a local variable on the stack of a function that has not exited while the threads are running.
I am willing to believe I should be more careful about the thread termination and should make sure that main()
does not exit without using pthread_join()
to ensure that the threads have exited first.
Example output:
$ make ptex
gcc -O ptex.c -o ptex
ptex.c: In function ‘main’:
ptex.c:40: warning: passing argument 4 of ‘pthread_create’ discards qualifiers from pointer target type
ptex.c:45: warning: passing argument 4 of ‘pthread_create’ discards qualifiers from pointer target type
$ ./ptex
writer(): pseudo_global = 1
main(): pseudo_global = 0
reader(): pseudo_global = 1
writer(): pseudo_global = 2
main(): pseudo_global = 2
reader(): pseudo_global = 2
writer(): pseudo_global = 3
main(): pseudo_global = 3
reader(): pseudo_global = 3
writer(): pseudo_global = 4
main(): pseudo_global = 4
reader(): pseudo_global = 4
writer(): pseudo_global = 5
reader(): pseudo_global = 5
main(): pseudo_global = 5
writer(): pseudo_global = 6
reader(): pseudo_global = 6
main(): pseudo_global = 6
writer(): pseudo_global = 7
reader(): pseudo_global = 7
main(): pseudo_global = 7
writer(): pseudo_global = 8
reader(): pseudo_global = 8
main(): pseudo_global = 8
writer(): pseudo_global = 9
reader(): pseudo_global = 9
main(): pseudo_global = 9
writer(): pseudo_global = 10 (exiting)
reader(): pseudo_global = 10 (exiting)
main(): pseudo_global = 10 (exiting)
$