Reputation: 417
So I have a little piece of code that in theory could be parrelized easily.
The structure is very simple, quite similiar to the following:
for (int i = 0; i < some_value; ++i) {
// we have a function called do_stuff
// somewhere in the code
// Create a new pthread
// using do_stuff as start routine
}
Now all the variables are not shared between the threads. That is, no inter-communication of variables between the threads is necessary. However I do use the variable i
to write data to arrays and such.
What I'm wondering is: if I pass the variable i
as argument for the pthread start routine and the value of i
changes (because i
gets incremented when in the next loop iteration), does the value of i
in the already existing threads also change?
Upvotes: 0
Views: 16359
Reputation: 444
If you provide a pointer to multiple threads, their behavior may modify the value(s) pointed in an undeterministic fashion. If you share variables between threads, you should use semaphors or mutexes to manage read/write accesses between threads.
If you know the threads only access different memory locations, there is no need for that. For instance, if each thread writes in the same array but for different indices, you don't need to protect the array.
EDIT:
If you provide the address of the variable i
then yes it will be modified outside the thread by the loop. If you create a temporary variable in the loop and pass its address, however, you'll be fine. This example might help you see what's happening:
http://timmurphy.org/2010/05/04/pthreads-in-c-a-minimal-working-example/
In C, anytime you provide a pointer to a function, the value it points to may be modified both from the inside and from the outside of that function (no matter whether or not it is on the same thread). pthread_create
requires you to provide the arguments of your start routine in the shape of a void *
, so anything that has a pointer to the same variable is able to modify its value at any time.
As @Shahbaz suggested, you might be interested in OpenMP. With OpenMP, you add pragmas to your code in order to facilitate thread creation. You also specify whether threads share a variable or not.
Upvotes: 1
Reputation: 47523
If you pass the address of i
to all functions, and they each try to modify it, well of course i
gets messed up because they all have the address of the same variable. What you need is to give each thread the range they need to work on and let them iterate over it with a local variable. Something like this:
struct thread_data
{
int start;
int end;
pthread_t tid;
};
struct thread_data td[N]; // assuming N threads
/* divide up the ranges */
for (i = 0; i < N; ++i)
td[i] = (struct thread_data){ .start = i*len/N, .end = (i+1)*len/N };
td[N-1].end = len;
/* create the threads */
for (i = 0; i < N; ++i)
pthread_create(&td[i].tid, NULL, func, &td[i]);
and in func:
void *func(void *arg)
{
struct thread_data *data = arg;
for (int i = data->start; i < data->end; ++i)
/* do some work */
}
You may also be interested in learning about OpenMP which is designed to automate exactly what you are asking for.
Upvotes: 5