2

So I have a scaled down version of an elevator program that uses pthreads in c. Each thread is an individual lift that calls function request(). I am not sure how to know which lift (1, 2 or 3) which are threads are using the function request. In the request function I need to print which thread used it at that time. Sorry if my explanation doesn't make complete sense.

void* request(void* abc)
{ 
    int ii;
    for(ii = 0; ii < 8; ii++)
    {
        sleep(1);
        printf("REQUEST FROM LIFT COMPLETED\n");
    }
}
int main()
{
    pthread_t lift1;
    pthread_t lift2;
    pthread_t lift3;

    pthread_create(&lift1, NULL, request, NULL);
    pthread_create(&lift2, NULL, request, NULL);
    pthread_create(&lift3, NULL, request, NULL);

    pthread_join(lift1, NULL);
    pthread_join(lift1, NULL);
    pthread_join(lift1, NULL);

    return 0;
}
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • The easiest solution would be to pass something else than NULL as the last parameter of `pthread_create()`, because that will be passed on to the request function (as `void* abc`) in your example. Edit: took a few seconds too long... Marco Bonelli has posted exactly what i meant – Felix G Apr 24 '20 at 14:19
  • 1
    `pthread_self()` will return the calling thread's `pthread_t`. Some code assumes that `pthread_t` is an integer, but that is not portable. See [How to print pthread_t](https://stackoverflow.com/questions/1759794/how-to-print-pthread-t). – Ian Abbott Apr 24 '20 at 14:22

1 Answers1

8

You could do this in multiple ways, the simplest one is to pass some meaningful value as thread parameter to identify each thread.

Here's an example:

void *request(void *data)
{ 
    const int id = *(const int *)data;
    int ii;

    for(ii = 0; ii < 8; ii++)
    {
        sleep(1);
        printf("REQUEST FROM LIFT %d COMPLETED\n", id);
    }
}

int main()
{
    const int id1 = 1, id2 = 2, id3 = 3;
    pthread_t lift1;
    pthread_t lift2;
    pthread_t lift3;

    pthread_create(&lift1, NULL, request, (void *)&id1);
    pthread_create(&lift2, NULL, request, (void *)&id2);
    pthread_create(&lift3, NULL, request, (void *)&id3);

    pthread_join(lift1, NULL);
    pthread_join(lift2, NULL);
    pthread_join(lift3, NULL);

    return 0;
}

You could also define those id varibles as static globals:

// Outside main:
static const int id1 = 1, id2 = 2, id3 = 3;
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • @CodingNoob24: since you are a coding noob :), keep in mind that you need to pass a pointer to an object which has a lifetime at least as long as your thread. This is a good example, but in practice you will likely create your threads without immediately joining them afterwards, so it would make sense to `malloc` those ids, or make them static. – vgru Apr 24 '20 at 14:28
  • 1
    Another common practice would be to cast the integer values to void* and pass them directly like `(void*)1`, `(void*)2`, etc. Now of course i'm not saying that it's a particularly _good_ practice, but it **is** common – Felix G Apr 24 '20 at 14:32
  • `&id1` in the last argument of the call to `pthread_create` may need an explicit cast to discard the const-ness to avoid a compiler warning. – Ian Abbott Apr 24 '20 at 14:35
  • @MarcoBonelli: that's why I wrote "but in practice you will likely create your threads without immediately joining them afterwards". I wasn't saying that this is incorrect (I already upvoted it), I just wrote a hint to the OP, since I've seen several questions about getting runtime faults due to these mistakes. – vgru Apr 24 '20 at 14:36
  • @Groo I initially thought this was addressed to me, sorry about that. Gotcha. – Marco Bonelli Apr 24 '20 at 14:37
  • @FelixG interesting, never seen that in practice (not that I have seen much code working with threads anyway). I wonder if that's valid... it looks like so from a C-standard point of view. – Marco Bonelli Apr 24 '20 at 14:42
  • @MarcoBonelli To be honest i haven't seen it that often in this particular context (pthreads), but passing integers this way to functions which accept some kind of user defined data (which is passed unmodified to some other function, like a callback), is - as far as i can tell - pretty common in C code (at least i have seen that a lot) – Felix G Apr 24 '20 at 14:47
  • @FelixG Technically, the result will be implementation defined as both the result of converting an integer to a pointer and the result of converting a pointer to an integer are implementation defined, so getting an identical integer from the round trip is not guaranteed. In practice, it tends to work on anything that supports Pthreads. – Ian Abbott Apr 24 '20 at 14:47
  • @FelixG yeah makes sense, Linux kernel code is full of this as an example now that I think about it. – Marco Bonelli Apr 24 '20 at 14:49