简体   繁体   中英

Sending multiple arguments to pthread_create()

This is a program from The Linux Programming Interface (original code here ). What I am trying to do is to send 2 "arguments" to threadFunc using pthread_create() for the goals listed below:

  1. First one serves as an iterator in the for loop in threadFunc();
  2. Second one identifies the thread that is currently doing work in threadFunc(). So it will be some sort of printable ID for the thread.

To achieve these goals I create this struct that contains 2 member variables:

struct arguments {
    int loops;
    pthread_t self;
};

And this function loops 'threadFuncLoops' times incrementing global variable 'glob'

static void * threadFunc(void *arg)
{
    struct arguments * threadFuncArgs = arg;
    int threadFuncLoops = *(arg.loops);

    for (int j = 0; j < threadFuncLoops; j++) {

        // Something happens to glob
    }

    return NULL;
}

In main() I am creating 2 threads (t1, t2) and send them to threadFunc():

    struct arguments newArguments;

    s = pthread_create(&t1, NULL, threadFunc, &newArguments);

    s = pthread_create(&t2, NULL, threadFunc, &newArguments);

But compiler says in threadFunc()

request for member 'loops' in something not a structure or union

My questions are:

  1. How come "loops" is not in a structure? It is in a struct instance isn't it?
  2. How exactly achieve goal #2?

Thank you very much.

You are taking the address of newArguments in the main function and passing that to your thread function. That means it's no longer a struct but a pointer to a struct , hence you will need to use -> .

You could use the other means of doing x->y , which is (*x).y and it looks like that may have been what you were trying to achieve with *(arg.loops) but there's two problems with that:

  • you're trying to dereference args.loops which is not a pointer - you should be doing (*args).loops ; and
  • args is the wrong type to dereference anyway, you need a pointer to the structure, so it would be (*threadFuncArgs).loops .

So, one way to fix this is to use this instead:

struct arguments * threadFuncArgs = arg;
int threadFuncLoops = threadFuncArgs->loops;

One other thing to watch out for. The pointer you pass to the two threads is a pointer to exactly the same memory. That means, if one of the threads changes, for example, the self field in the structure, it will change for both.

Normally, you would fix this in one of (at least) two ways:

  • have an array of structures and make sure that each thread gets a unique one, only for itself; or
  • have the thread copy its information into local storage, though that will require some re-engineering to ensure the main function doesn't create the second thread until this is done.

you have to use "->". Replace arg.loops by threadFuncArgs->loops.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM