You are not logged in.

#1 2013-05-15 14:43:50

prasinoulhs
Member
From: Greece
Registered: 2011-10-30
Posts: 53

[SOLVED] C + pthread Threads messing with each other.

On the following code seems like each threads uses the same tparams variable. Although just before the thread is created the count value is corrent when the thread is called, the value seems to be the same. Now if i say put a sleep(5) after each thread is created then everything is fine. What am i missing here?

#include "stdio.h"
#include "stdlib.h"
#include "sys/time.h"
#include "pthread.h"

#ifndef N
#define N 8
#endif

#ifndef STOP
#define STOP 1
#endif

#ifndef THREADS
#define THREADS 4
#endif

typedef struct
{
    int count, lines;
} Params;

void * thread_func(void *);
void * f(void *);

int main(int argc, char const *argv[])
{
    Params p = {1, N};
    thread_func(&p);

    return 0;
}

void * thread_func(void * params)
{

    Params *p = (Params *)params;

    pthread_t threads[THREADS];

    Params tparams = {2, p->lines/THREADS};
    int thread;
    for (thread = 0; thread < THREADS; thread++)
    {
        tparams.count = thread;
        printf("I will call someone %d\n", tparams.count );
        pthread_create(&threads[thread], NULL, f, &tparams);
    }

    for (thread = 0; thread < THREADS; thread++)
        pthread_join(threads[thread], NULL);

    return NULL;
}

void *f (void * pa){
        Params p = *(Params *)pa;
        printf("Somebody called me\t %d\n", p.count);
        pthread_exit(NULL);
}

Last edited by prasinoulhs (2013-05-15 23:42:33)

Offline

#2 2013-05-15 16:17:23

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,347

Re: [SOLVED] C + pthread Threads messing with each other.

I would say you can spawn threads much faster than they actually begin to execute.  Perhaps you could set up some (better) synchronization method that blocks the spawning of additional threads until after the count is updated by each new thread.

I am obliged to point out that this looks very much like it may run afoul of our homework policy.

If this is homework, okay, but say so so that we can guide you as teachers.
If not, what are you actually trying to do?

Last edited by ewaller (2013-05-15 16:17:58)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#3 2013-05-15 16:58:37

prasinoulhs
Member
From: Greece
Registered: 2011-10-30
Posts: 53

Re: [SOLVED] C + pthread Threads messing with each other.

ewaller wrote:

I would say you can spawn threads much faster than they actually begin to execute.  Perhaps you could set up some (better) synchronization method that blocks the spawning of additional threads until after the count is updated by each new thread.

I thought of this, so i moved the declaration of tparams inside the for loop, making it's scope local, but the same think happens.

ewaller wrote:

I am obliged to point out that this looks very much like it may run afoul of our homework policy.

If this is homework, okay, but say so so that we can guide you as teachers.
If not, what are you actually trying to do?

Yes, this is homework, but i already have a solution, you could create an array of params for each thread, but this doesn't seem right.

If you think this shouldn't be here then you can delete it.
Anyway thanks for your time.

Offline

#4 2013-05-15 17:33:34

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,347

Re: [SOLVED] C + pthread Threads messing with each other.

I have no issues with homework help -- in fact I think it is great.  Just be sure and tell us it is homework. 

If one does not identify the post as homework, someone here is likely to post a solution, complete with sample code.  That does not help you, and raises ethical issues.  If we know it is homework, we can nudge you in the correct direction.

so i moved the declaration of tparams inside the for loop, making it's scope local, but the same think happens.

Not quite what I meant.  Suppose the call that launches the thread creates a pointer, initiates a non blocking system call to start the thread, and immediately returns.  You might be able to power through your loop without ever having the main thread getting swapped out.  What would happen if the system call mucked around for 1 millisecond before actually executing the first line of code in the new threads?  What if the threads that are being spawned don't get any processor time until 100s of microseconds after the loop in main finishes?  Did you know that most "sleep" functions cause the calling thread to sleep until the event times out, allowing other threads to run?

EDIT: How do you have any guarantee they start in the order you think they start?  What if one were started on a different processor and that processor changed context sooner than a processor on which an earlier thread had been started?

What if, before you started a thread, the main loop set a flag in tparms that indicated the thread had not started.   Then, inside the new thread, update count, and then clear the start flag.  Meanwhile, back in the main loop, after starting the new thread, you would stop and wait for the flag to magically change from 1 back to 0.  This is basically a semaphore.

Now.  There are some serious practical problems with this.  First, you have to make certain that the compiler does not optimize out the fact that a different thread can change a value.  Also, there are other concerns about thread safety that could cause problems.  Also, if you just write a loop that spins on a value, you are wasting processor time.  That is why most practical thread mechanisms include functions for pipes, mutexs, semiphores, etc...  (hint)

Last edited by ewaller (2013-05-15 17:54:23)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#5 2013-05-15 19:20:39

prasinoulhs
Member
From: Greece
Registered: 2011-10-30
Posts: 53

Re: [SOLVED] C + pthread Threads messing with each other.

What you say is, before the new thread "copies" the data the next loop comes in and changes the data?

Isn't this "solved" if you move the declaration inside the loop, making it so each time the loop gets executed the tparams is disposed and then recreated resulting in a different variable (unless the new variable gets the same address which i would expect should't be allowed to happen since it's still in use by pthread_create), so each thread has each own copy if none of them start before the loop finishes?

Each thread should have it's set of data there is no need to share.

I don't think that i need to use semaphores since the threads don't exchange data, and they shouldn't operate on the same data, plus this is supposed to show the speedup that we can achieve by using threads.

So my real question is can i (always) create two threads one after the other like this? Am i missing something or this may or may not work depending on the circumstances?

....
//declare args

pthread_create(&thread1, NULL, f, &args);
//change something in args
pthread_create(&thread1, NULL, f, &args);

Offline

#6 2013-05-15 21:12:54

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,347

Re: [SOLVED] C + pthread Threads messing with each other.

You are not copying anything when you spawn threads.  In main, you allocate storage for Params called p and initialize it.  You then call your function that spawns all the threads (thread_fun), and you do allocate another Params variable called tparams. You copy the elements of main's p into tparams.   You then pass the address of tparams to the function that spawns new threads (f),  that function then takes that pointer (i.e. the address of the storage that was allocated in thread_fun) and saves the address it points to in the local copy of p (which is a pointer) unlike the tparams, which is a variable that is stored in memory allocated for it.  Every thread that is spawned has a new local version of p (a pointer) and they all point back to the exact same Params called tparams that was allocated in thread_fun.  If any one of the threads change something pointed to by their copy, they are changing the one and only Param called tparams.  Every thread that is forked are all referencing data stored in the same location in memory.  If any thread changes something, every thread will see the change.  The thing you have to be VERY careful of is changing something when another thread is not expecting it to change.  Note that the very first p, why back in main, is not touched by all of the threads.  Only tparams is changed, and tparams was created by allocating memory and copying the elements from the p allocated in main.

Edit:  Fixed some inaccuracies

Last edited by ewaller (2013-05-15 23:13:43)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#7 2013-05-15 23:42:14

prasinoulhs
Member
From: Greece
Registered: 2011-10-30
Posts: 53

Re: [SOLVED] C + pthread Threads messing with each other.

Oh i thought that when the new thread spawned it would somehow copy the parameters. It makes sense now.

Thank you for your time.

Offline

Board footer

Powered by FluxBB