VLAs with threads

A

Aggelidis Nikos

hi to all,

i have a question concerning threads and vlas.

It is a know fact that pthreads share the same address space. I thought
that this meant that whatever variable i had in main() before creating
a thread, i would be able to use in the thread-itself. Unfortunately
threads have different stacks and that means that any local variable of
main can't be used by threads.

So in order for a variable to be used inside a thread, i see 2 options.
1) pass the variable as an argument to the thread
2) have a global variable that anyone can modify


The problems begin when i decided that i wanted to use a c99 feature:
the variable length arrays {vla}. The problem is that i can't declare a
gloval vla {it isn't permitted by the language}. Also i can't have a vla
inside a structure.... so what can i do?


I don't know if the context of my problem is relevant but for what is worth:

i want to have a 2d vla and i want to be able to "alter" it through threads...


thanks for your time,
nicolas
 
A

Antoninus Twink

It is a know fact that pthreads share the same address space. I thought
that this meant that whatever variable i had in main() before creating
a thread, i would be able to use in the thread-itself. Unfortunately
threads have different stacks and that means that any local variable of
main can't be used by threads.

There's a good reason for that. If a variable with automatic storage
could be accessed by any thread, when would you suggest it gets
destroyed?
The problems begin when i decided that i wanted to use a c99 feature:
the variable length arrays {vla}. The problem is that i can't declare a
gloval vla {it isn't permitted by the language}. Also i can't have a vla
inside a structure.... so what can i do?

Create your array on the heap with malloc() instead, protect accesses to
it using a mutex, and decide for yourself when the right time is to
free() it.
 
A

Aggelidis Nikos

Create your array on the heap with malloc() instead, protect accesses to
it using a mutex, and decide for yourself when the right time is to
free() it.

but vla's where introduced to solve numeric problems. That's why i want to
use vla...
 
A

Antoninus Twink

but vla's where introduced to solve numeric problems.

What do you mean? The only possible advantage I can think of of a VLA is
that if you have a heavily-called function then the time savings from
twiddling the stack pointer instead of calling malloc()/free() might be
significant. A big disadvantage of VLAs is that it isn't possible to
detect and attempt recovery if the allocation fails.
That's why i want to use vla...

Use the appropriate tool for the job. A VLA is not a good vehicle for
inter-thread communication.
 
A

Aggelidis Nikos

Use the appropriate tool for the job. A VLA is not a good vehicle for
inter-thread communication.

thanks for the advice Antnoninus, it seems that you are right, i will
revert back to classic malloced arrays...

-nicolas
 
V

viza

Hi

It is a know fact that pthreads share the same address space. I thought
that this meant that whatever variable i had in main() before creating
a thread, i would be able to use in the thread-itself. Unfortunately
threads have different stacks and that means that any local variable of
main can't be used by threads.

Not true at all. You just can't access it by *name*.

void *thread( void *ptr ){

void **args_on_stack2= ptr;

fputs( args[0], args[1] );

some_OT_interthread_communication_function( SEND );

return NULL;
}

int main( void ){

/* ... */
{
void *args_on_stack1[]= { "Hi mum!\n", stdout };

some_OT_thread_making_function( thread, args_on_stack1 );

some_OT_interthread_communication_function( WAIT );
}
/* ... */
}

This is completely safe as long as there is no way for the
communication function to return before the other thread has finished
with the variables, or copied them onto its own stack. As long as the
function doesn't return then the variables are kept on the first
stack.
So in order for a variable to be used inside a thread, i see 2 options.
1) pass the variable as an argument to the thread

in (OT) pthreads you only get one (void*) for that.
2) have a global variable that anyone can modify
Yuk!

The problems begin when i decided that i wanted to use a c99 feature:
the variable length arrays {vla}.

OK. I don't think it's possible to implicitly pass the array size so
that sizeof works, but that is true of any automatic array that you
pass by pointer. You can still have a variable length array in one
thread, and pass the other thread a pointer to it and the length of it
in an integer type.

HTH
viza

PS:
I use this regularly and it works(TM) in practice, at least on i386
and amd64, I'm but interested to hear any academic criticisms that
anyone might have.
 
R

Richard Tobin

but vla's where introduced to solve numeric problems.
[/QUOTE]
What do you mean?

I don't know if it's what's being referred to here, but there's
an obvious use for C99's VLAs in numerical work:

int invert(int n, double matrix[n][n]);

- a construct which many programmers had lamented the lack of over a
couple of decades.

In this case of course there is no allocation.

-- Richard
 
S

Szabolcs Borsanyi

What do you mean? The only possible advantage I can think of of a VLA is

Well, if the OP wants variable length arrays, let's do that, he might
have a good reason: e.g. he has a well tested set of routines for vlas,
and he is trying to port it to a multicore system.

Posix threads are not standard C, but let's not cancel the discussin at this
point. Posix threads allow one single void* to pass to a function executed
in a separate thread. The OP wants now to use this to pass a vla.

One typically creates a struct that contains all the desired data to pass,
and one gives the pointer to this struct (converted to void*) to
pthread_create().

If the question was about a one-dimensional array, I'd suggest the flexible
array member. With two dimensions, I'd better let the OP declare the array
in the main, and put a pointer to it (or the its first subarray) into the
sturct of parameters.

Let me show an example:

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

struct parameters {
int n;
void *array;
};

void* thread(void*P)
{
int n=((struct parameters*)P)->n;
double (*A)[n]=((struct parameters*)P)->array;
/* now you have n and A exactly as if you had a prototype, like
thread(int n,double A[n][n])
*/
for(int i=0;i<n;i++,puts("")) for(int j=0;j<n;j++) printf("%g ",A[j]);
return NULL;
}

int main()
{
int n=4;
double A[n][n];
for(int i=0;i<n;i++) for(int j=0;j<n;j++) A[j]=10*i+j;
struct parameters P={.n=n,.array=(void*)A[0]};
pthread_t T;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&T,&attr,thread,&P); /* error checking ... */
pthread_join(T,NULL);
}

Szabolcs
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top