How to pass arguments to threads in C

Поделиться
HTML-код
  • Опубликовано: 29 дек 2024

Комментарии • 113

  • @mariuszk8339
    @mariuszk8339 4 года назад +105

    We can pass address of position in array instead index "i", ie: "primes+i". I guess...

    • @CodeVault
      @CodeVault  4 года назад +31

      Yep, that's what I was looking for in an answer. Good job!

    • @zakariafahim3432
      @zakariafahim3432 3 года назад +3

      @@CodeVault Can we add a mutex on i ?

    • @marco8673
      @marco8673 3 года назад +2

      @@CodeVault i have a question, if you pass "primes+i",
      then you would have primes[primes+i], is this expression correct?
      i mean shouldn't you also change in the function routine:
      primes[index]------>*(int*) arg or something like that

    • @omeryacine8281
      @omeryacine8281 3 года назад +3

      @@marco8673 no, u would just need to dereference the arg pointer (which is equal to primes+i), and this place in memory would contain the number you are looking for.

    • @marco8673
      @marco8673 3 года назад +1

      @@omeryacine8281 ok thank you!

  • @alihelbah8579
    @alihelbah8579 3 года назад +24

    I am so happy to watch all these videos on this channel. He is genuinely one of the best teachers. I am really new to threads and c programming in general and he is making it so much easier on new programmers to learn. He starts with giving examples on how we would first think to approach an issue then tells us what is wrong with it and how we can improve it. I really like the way he teaches. thank you

  • @saltysyracusian
    @saltysyracusian 3 года назад +14

    this man is a saint.

  • @ayushanand18
    @ayushanand18 Год назад +1

    Man you are no less than God to me! You explain such complex concepts and debug stuff so easily, you are amazing.

    • @Panthera-Uncia
      @Panthera-Uncia 8 месяцев назад

      You Indians would worship anything.

  • @innovationsurvival
    @innovationsurvival 2 года назад +4

    Utterly hilarious video. I just ran into this exact situation six hours ago as I began to develop a test multi-threading program. After staring at the screen for two hours trying to figure out what was wrong, I solved it using a small const static array of values and used the loop index to index into the array and pass the address of the array element.
    KABOOM, problem solved.
    I did not need malloc() or free() because the small array was static in memory, trading off a little space for a little memory management processing.
    Great videos, absolutely tremendous. I'm so glad to have stumbled on your channel and have enjoyed several of your very informative videos.
    Thank you, thank you, thank you.

  • @oiramormedeiros
    @oiramormedeiros 3 года назад +7

    You are my hero!

  • @firedemon2014
    @firedemon2014 2 года назад +3

    I just really appreciate all of your videos, very informative and easy to follow

  • @gauravghati
    @gauravghati 3 года назад +6

    we can also pass value of a variable i by casting it as (void *) then in function we can again cast to int.. no need to allocate and deallocate for that.
    PS: you have the best OS coding videos, thanks! :)

    • @CodeVault
      @CodeVault  3 года назад +4

      Yeah, that's a trick you can use

    • @attilatorok5767
      @attilatorok5767 3 года назад

      I think that type of type punning violates strict aliasing and it can have problems with old arm processors because of alignment

    • @busbug5457
      @busbug5457 2 года назад

      that's what i looking for ty

    • @mortenlund1418
      @mortenlund1418 6 месяцев назад +2

      Works like a charm :)

  • @drmabusedesporte2285
    @drmabusedesporte2285 3 года назад +1

    I think that a remark on 12:16 "every single pointer has the same size" is a bit of a gaffe / misleading in the context of the free() call, because what we are actually freeing is a chunk of memory allocated by malloc. It's probably more relevant (and I guess valid in most cases) concerning the implicit conversion as we provide a (int *) as an argument to the pthread_create() which expects (void *).

    • @CodeVault
      @CodeVault  3 года назад +1

      That conversion is what I was referring to there. Thanks for the feedback nonetheless!

  • @ivanlo7195
    @ivanlo7195 3 года назад +2

    fk, you are too good, I literally encounter the exact same problem of having duplicated value of i after passed to the thread function. You saved me

  • @marco8673
    @marco8673 3 года назад +4

    thanks for the lesson! better than my univeristy...

  • @ssbitar
    @ssbitar 2 года назад +4

    Excellent example and explanation. In pthread_create(), could you just pass in &primes[i] as the argument?

    • @CodeVault
      @CodeVault  2 года назад +6

      Exactly. That's the more simple answer

  • @michael22nguyen
    @michael22nguyen 6 месяцев назад

    Thank you for the video I definitely learn a lot from you. I think one important thing to mention too is that declaring the malloced int* also needs to happen inside the loop or else you you would pass the same pointer and free would free the value sometimes before other threads can use it. I had the same setup but assigned into an int of a struct and had double freeing issues because of this. Still trying how to figure out a way around this though while passing struct if there are any ideas I am all ears. :)

    • @CodeVault
      @CodeVault  3 месяца назад

      Yea, either allocate an array of int and pass a pointer to each of them or simply pass the value directly (and forcefully cast to pointer) if you only need to read it on the thread function

  • @Dudeitsbrian
    @Dudeitsbrian Год назад

    Great video, thanks hugely. I was struggling with arguments in the pthread routine for a while

  • @mohammadahsan7873
    @mohammadahsan7873 4 года назад +1

    Very Nicely Explained.
    Thanks a lot.
    Wish you a happy new year ahead.

  • @fabv1966
    @fabv1966 2 года назад

    apparently putting the sleep function after the pthread_create function works too lol thanx for your videos !!

  • @drdriven
    @drdriven Месяц назад +1

    literal saviour

  • @LucaPalamenti
    @LucaPalamenti 3 месяца назад

    extremely helpful explanation!

  • @joaopereira685
    @joaopereira685 2 года назад +1

    I dont understand why with this solutuion we wouldnt bump into the same problem, that is, when routine is sleeping but the for loop goes on, why doesnt the value of a get erased when we malloc it?

    • @CodeVault
      @CodeVault  2 года назад +2

      The value of a DOES get overwritten, that is correct. The difference is that we are no longer passing the address of a to the threads but we are passing a totally new part of memory that has been allocated with malloc to each thread. So, while, a itself may change, the value that was already passed to each thread doesn't.
      pthread_create(&th[i], NULL, &routine, &i); // here &i is always the EXACT same value (the address to the local variable i, which we know it changes in the for loop). Since we're passing the same value (which represents the address to i), whenever we change i in one thread (in the for loop for example) it changes for all the threads since they are all looking at the exact same part of memory.
      int* a = malloc(sizeof(int));
      *a = i;
      pthread_create(&th[i], NULL, &routine, a); // here a is different for each iteration of the for loop. So on the next iteration, even though a itself changes, the value that we passed to each thread didn't (that value represents the address to which we stored the value of i for that thread)

    • @joaopereira685
      @joaopereira685 2 года назад

      @@CodeVault Thanks a lot for your response! And thank you also for making quality content

  • @MdAbdullahAlFahim
    @MdAbdullahAlFahim 3 года назад +3

    First of all, THANK YOU very much for your recent playlists especially the UNIX ones. These lectures are very helpful and organized!
    I have a question which is unrelated to thread but arose from this example you showed. Inside the loop, instead of dynamically allocating new integers in each iteration, I just used ``int idx = i;'' hoping in each iteration a new int variable (idx) would be created from stack memory. Printing the address of this idx variable, I notice the addresses in each interactions are same, which indicates the idx variable is only created once and reused in all iterations. Is my understanding correct? It looks unintuitive though. I thought int idx = i; would declare and initiate new variables in each iteration.

    • @CodeVault
      @CodeVault  3 года назад +3

      It's correct
      for (i = 0; i < 10; i++) {
      int idx = i;
      }
      idx would only be defined once even though its initialization (to the value of i) will be executed multiple times.
      In fact, it does make sense. In 99% of the cases you only need one place to store the variable for all the iterations. It's really only this case that can cause issues. That is why we have dynamically allocated memory, to be able to control exactly when memory is allocated and deallocated.
      Basically any pair of { } inside a function defines only one set of each defined variable (regardless if it's a for loop, while loop or an if). But if you call that function multiple times those variables will get deallocated (when the function exits) and allocated again when the function starts executing again.
      I might make a video on this topic as it's quite interesting

    • @MdAbdullahAlFahim
      @MdAbdullahAlFahim 3 года назад +1

      @@CodeVault It makes sense. Thanks for your reply!
      I wish you all the best.

  • @kshitijsingh5728
    @kshitijsingh5728 2 года назад +1

    When 'i' was declared inside the 'for' loop, why wasn't that giving an error on accessing its location after 1 sec as it would definitely have been out of scope(and deleted) in due course of time? It is instead giving a value of 10, does that mean it didn't get deleted on exit from the 'for' loop?

    • @CodeVault
      @CodeVault  2 года назад +3

      No. 'i' is a local variable to the main function. It gets deallocated only after the whole function finishes its execution (which is after the pthread_joins are called). So that 'i' remains allocated in memory.
      What you're talking about there is the visibility scope of that 'i' variable. It's defined in the for loop so I can't use it outside of that for loop, but its memory is located on that main function's stack

  • @abdullahh-1
    @abdullahh-1 3 года назад +2

    Man you are a life saver!

  • @marco8673
    @marco8673 3 года назад +1

    i have a question, if you pass "primes+i",
    then you would have primes[primes+i], is this expression correct?
    i mean shouldn't you also change in the function routine:
    primes[index]------>*(int*) arg or something like that

  • @muhammadtaimourafzal5285
    @muhammadtaimourafzal5285 3 года назад +1

    can you make a video on how to pass multiple parameters using a thread. for example you want to pass an array and its size. how do we do it?

    • @CodeVault
      @CodeVault  3 года назад +2

      Sure! The idea is you just pass a struct for that. I'll make a video on it in the future

    • @muhammadtaimourafzal5285
      @muhammadtaimourafzal5285 3 года назад

      @@CodeVault yeah i just did that yesterday

    • @vaibhaves
      @vaibhaves 3 года назад +2

      @@CodeVault can you send a sample code?

  • @MayankSharmaee23b045
    @MayankSharmaee23b045 7 месяцев назад

    how are two threads created at i=0 since the input to pthread_create is &th[i] so it must wait for the i value right

    • @CodeVault
      @CodeVault  7 месяцев назад

      There is no intrinsic wait in the loop

  • @maltesetoy3653
    @maltesetoy3653 3 года назад

    I think that the simple solution is to create pointer of pointers that each thread will get the address of current index of the pointers array

    • @CodeVault
      @CodeVault  3 года назад

      That's an option as well. Depends what you want to do really. You could also pass the value itself, instead of a pointer

  • @prathapbillgates
    @prathapbillgates 3 года назад +1

    You are really great!!! Can you make IPC shared memory and message passing concept video?

    • @CodeVault
      @CodeVault  3 года назад

      Yea, they are on my list

  • @onursimsek6094
    @onursimsek6094 3 года назад +1

    Is there any way that we can see them in the order that they were in array?

    • @CodeVault
      @CodeVault  3 года назад +1

      Yes, you could with semaphores. But frankly, it's redundant. Just use one thread instead to print them in order and don't worry about synchronization issues.

  • @vivekkashyap157
    @vivekkashyap157 Год назад

    for(int i = 0; i < THREAD_NUM; i++)
    {
    if(pthread_create(&th[i], NULL, &dice, &i) != 0){
    return i;
    }
    }
    In this case, when i is 9, and thread_create function is called during this, for loop is completed i is 10, now, i is local variable so, it is destroyed so, why index is printing 10?
    When not segmentation fault?

    • @CodeVault
      @CodeVault  Год назад

      It's not destroyed if you are using pthread_join. The value is ten because the loop finishes execution before any of the threads have a chance to start executing

  • @gabriela-807
    @gabriela-807 Месяц назад

    I understood what you meant, but I didn't understand how each thread sees the correct index just because it allocated a space in memory. Doesn't each thread, when it starts and enters the function, run the risk of accessing the same index? Why didn't you use the mutex in this case?
    Excuse my English, I'm using the translator

    • @CodeVault
      @CodeVault  Месяц назад

      Not really, each thread gets created with a different input index therefore there is not issue accessing the same index. Actually, in this case it wouldn't even matter since we are only reading the values. Parallel reading of data is fine, only when writing do race conditions become a problem

  • @rouanemouaad
    @rouanemouaad 2 года назад +1

    or you can just pass :
    pthread_create(threads+i, NULL, display,(void *)(primes+i));
    and since primes+i is a fixed address, once we passes it to our function we will never have a problem. i'm right ?

    • @CodeVault
      @CodeVault  2 года назад +2

      Yep, that's true for pointers. Another trick you can use if you want to pass a value (not a pointer) is:
      pthread_create(threads + i, NULL, &routine, (void*) 17);
      And, if you treat that arg in the routine function like an integer instead of a pointer, it will work just fine

  • @rickywong9525
    @rickywong9525 Год назад

    Why not just pass the value like this: "&primes[i]"? Then in the routine function, typecase the void * to int * and dereference it like this: "printf("%d
    , *num)" to print it out? Is this a bad approach?

    • @CodeVault
      @CodeVault  Год назад +1

      Yep, that's the better way of doing it

  • @fernandaeschallots2485
    @fernandaeschallots2485 3 года назад

    Your video is the best. thx so much

  • @chnsnyz
    @chnsnyz Год назад

    what if I create the routine function as void* routine(int arg) and pass i value? It works also. And you dont have to allocate dynamic memory. There is a downside?

    • @CodeVault
      @CodeVault  11 месяцев назад +1

      No. That is also a solution. The only downside is that the API expects the function to be defined as void* routine(void* arg) and it might show you some warnings. Usually I keep the signature of the function as is and just cast arg to int

  • @soniablanche5672
    @soniablanche5672 Год назад

    aren't function pointers smaller than "normal" pointers ?

    • @CodeVault
      @CodeVault  11 месяцев назад

      Usually they are the same size

  • @Anonymous-nn5wn
    @Anonymous-nn5wn 3 года назад +1

    Could you do the same using mutex In the critical section

  • @udamaefule7728
    @udamaefule7728 3 года назад

    please could you explain how you would make the output print in order.. im asking because I am using what you have explained here to help me figure out how to approach my assigment.. for some reason my threads arent executing in order and I need to fix that.
    Thank you once again, your vids are a lifesaver

    • @CodeVault
      @CodeVault  3 года назад

      Well, threads are meant to NOT be executed in order. If you want to execute something in order, simply DON'T use threads.
      Now, if you absolutely want to use threads for this you could technically use a set of semaphores

    • @VndNvwYvvSvv
      @VndNvwYvvSvv Год назад

      Reas about preemption and atomic operations. You can't force them to work in order if it's multi threaded. To print in order, you could have them return values then have main print sequentially, or if it has to be printed in the threads, you would need some kind of semaphore to wait when done, have main wait until all are done, then release each semaphore in order BUT again you then need a signal that each thread has finished printing before you unlock the next.

  • @navidnouri151
    @navidnouri151 3 года назад

    Thank you!

  • @gure1234321
    @gure1234321 3 года назад

    thanks for the help!

  • @kasimanvenky2539
    @kasimanvenky2539 3 года назад

    how we will get i value of same i=1 both threads please give some explanation about that.

    • @CodeVault
      @CodeVault  3 года назад

      If all you pass is an address to that i... That i can only have 1 unique value for ALL the threads it probably won't be 1 but it will be the value it exits from that for loop

  • @benjaminschwartz8275
    @benjaminschwartz8275 3 года назад

    You're a hero

  • @saadnazir13
    @saadnazir13 2 года назад

    I want to write a code in thread which reads the file how can do it?

    • @CodeVault
      @CodeVault  2 года назад +1

      Here's a video on how to read/write from files: code-vault.net/lesson/pt6uwax8pw:1603733523045

  • @ferxoorubio
    @ferxoorubio 3 года назад +1

    Can u simply pass &primes[i] ?

    • @CodeVault
      @CodeVault  3 года назад +1

      Yeah that should also work!

  • @piero8284
    @piero8284 2 года назад

    I just didnt understand why the numbers were not in order in the last output

    • @CodeVault
      @CodeVault  2 года назад

      That's because each thread prints out an element of the array and threads aren't guaranteed to execute in order

  • @yashkumarsoni1242
    @yashkumarsoni1242 Год назад

    What is the use of pthread join

    • @CodeVault
      @CodeVault  Год назад +1

      pthread_join basically waits for the specified thread to finish execution. Without it, the main process might finish execution before all the threads finish and that would stop the threads that were still running

  • @edsonbaptistafinda3312
    @edsonbaptistafinda3312 4 месяца назад

    I used a static variable and a mutex and it actually worked.
    void *f(void *index)
    {
    pthread_mutex_lock(&mtx);
    static int i;
    printf("
    Thread %d --> got number %d

    ", i, array[i]);
    i++;
    pthread_mutex_unlock(&mtx);
    return NULL;
    }

  • @balaganeshn4442
    @balaganeshn4442 3 года назад

    how to get the proper order output ?

    • @CodeVault
      @CodeVault  3 года назад +1

      You could use semaphores or mutexes... Although, if you want them in order you could simply execute the print function in a for loop in the same thread (usually tasks like these are better suited for single-threaded applications)

  • @georggbess9547
    @georggbess9547 4 года назад +1

    Very good videos on the youtube channel but too bad our concerns are being ignored on the discord server

    • @CodeVault
      @CodeVault  4 года назад +2

      I'm sorry about that. Getting quite a lot of questions every day. If you didn't get an answer right away try sending me a message. I'm trying my best to keep up with all the questions but there are a few here and there that I miss.

    • @CodeVault
      @CodeVault  4 года назад +2

      Also, please do note that I do not usually respond to questions I don't know the answer to and aren't related to any of the lessons posted.

  • @mwid23
    @mwid23 3 года назад

    can someone explain how to change the code to primes+I?

    • @CodeVault
      @CodeVault  3 года назад

      What do you want changed?

    • @tharindumandusanka7708
      @tharindumandusanka7708 3 года назад +1

      #include
      #include
      #include
      #include
      int primes[10] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };
      void* routine(void* arg) {
      sleep(1);
      int index = *(int*)arg;
      printf("%d ",index);
      // free(arg);
      }
      int main(int argc, char* argv[]) {
      pthread_t th[10];
      int i;
      for (i = 0; i < 10; i++) {
      //int* a = malloc(sizeof(int));
      //*a = i;
      if (pthread_create(&th[i], NULL, &routine, primes+i) != 0) {
      perror("Failed to created thread");
      }
      }
      for (i = 0; i < 10; i++) {
      if (pthread_join(th[i], NULL) != 0) {
      perror("Failed to join thread");
      }
      }
      return 0;
      }

  • @shaharrefaelshoshany9442
    @shaharrefaelshoshany9442 3 года назад

    best content

  • @poincareelcartografo5406
    @poincareelcartografo5406 Год назад

    I've successfully done it by passing the thread array as an argument and using their ids:
    pthread_create(&th[i], NULL, &primeSelect, th);
    void* primeSelect(pthread_t* arg)
    {
    int i = 0;
    int match = 0;
    do
    {
    if(pthread_self() == arg[i]) match = 1;
    else i++;
    }while(!match)
    printf("%d
    ", primes[i]);
    }

    • @CodeVault
      @CodeVault  Год назад

      That's a very creative idea. Very nice, good job!

  • @abhaygaikwad6251
    @abhaygaikwad6251 2 года назад

    understood

  • @diogoferreira7396
    @diogoferreira7396 Год назад

    i love you so much

    • @CodeVault
      @CodeVault  Год назад

      You can support the channel over on: code-vault.net/support-us

  • @throwaway8342
    @throwaway8342 2 года назад +1

    My implementation:
    #include
    #include
    #include

    int j = 0;
    int primes[] = {2, 3, 5, 7, 11, 13, 17, 19 ,23, 29};
    pthread_mutex_t mutex;

    void* routine(){
    int* res = malloc(sizeof(int));
    pthread_mutex_lock(&mutex);
    *res = primes[j++];
    pthread_mutex_unlock(&mutex);
    return (void*) res;
    }

    int main(int argc, char const *argv[])
    {
    pthread_t threads[10];
    pthread_mutex_init(&mutex, NULL);
    for(int i = 0; i < 10; i++){
    pthread_create(&threads[i], NULL, &routine, NULL);
    printf("Thread %d has started
    ", i);
    }
    for(int i = 0; i < 10; i++){
    int *res;
    pthread_join(threads[i], (void **) &res);
    printf("Running of thread is finished returning %d
    ", *res);
    free(res);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
    }

    • @CodeVault
      @CodeVault  2 года назад +2

      That's also a nice solution. The only problem is that now, you can't fully run all the threads in parallel due to the mutex