How to pass arguments to threads in C

แชร์
ฝัง
  • เผยแพร่เมื่อ 18 ต.ค. 2024

ความคิดเห็น • 110

  • @mariuszk8339
    @mariuszk8339 3 ปีที่แล้ว +102

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

    • @CodeVault
      @CodeVault  3 ปีที่แล้ว +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 ปีที่แล้ว +23

    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 ปีที่แล้ว +13

    this man is a saint.

  • @firedemon2014
    @firedemon2014 2 ปีที่แล้ว +3

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

  • @oiramormedeiros
    @oiramormedeiros 3 ปีที่แล้ว +7

    You are my hero!

  • @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 5 หลายเดือนก่อน

      You Indians would worship anything.

  • @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 ปีที่แล้ว

      that's what i looking for ty

    • @mortenlund1418
      @mortenlund1418 3 หลายเดือนก่อน +2

      Works like a charm :)

  • @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.

  • @marco8673
    @marco8673 3 ปีที่แล้ว +4

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

  • @michael22nguyen
    @michael22nguyen 4 หลายเดือนก่อน

    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  หลายเดือนก่อน

      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

  • @ivanlo7195
    @ivanlo7195 2 ปีที่แล้ว +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

  • @Dudeitsbrian
    @Dudeitsbrian ปีที่แล้ว

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

  • @fabv1966
    @fabv1966 2 ปีที่แล้ว

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

  • @mohammadahsan7873
    @mohammadahsan7873 3 ปีที่แล้ว +1

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

    • @CodeVault
      @CodeVault  3 ปีที่แล้ว +1

      Happy new year!

  • @drmabusedesporte2285
    @drmabusedesporte2285 2 ปีที่แล้ว +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  2 ปีที่แล้ว +1

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

  • @LucaPalamenti
    @LucaPalamenti 25 วันที่ผ่านมา

    extremely helpful explanation!

  • @ssbitar
    @ssbitar ปีที่แล้ว +4

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

    • @CodeVault
      @CodeVault  ปีที่แล้ว +6

      Exactly. That's the more simple answer

  • @MdAbdullahAlFahim
    @MdAbdullahAlFahim 2 ปีที่แล้ว +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  2 ปีที่แล้ว +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 2 ปีที่แล้ว +1

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

  • @abdullahh-1
    @abdullahh-1 3 ปีที่แล้ว +2

    Man you are a life saver!

  • @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

  • @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

  • @fernandaeschallots2485
    @fernandaeschallots2485 3 ปีที่แล้ว

    Your video is the best. thx so much

  • @gure1234321
    @gure1234321 3 ปีที่แล้ว

    thanks for the help!

  • @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

    • @CodeVault
      @CodeVault  3 ปีที่แล้ว

      Yes, that's correct

  • @navidnouri151
    @navidnouri151 2 ปีที่แล้ว

    Thank you!

  • @benjaminschwartz8275
    @benjaminschwartz8275 2 ปีที่แล้ว

    You're a hero

  • @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

  • @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

  • @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

  • @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.

  • @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

  • @vivekkashyap157
    @vivekkashyap157 11 หลายเดือนก่อน

    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  11 หลายเดือนก่อน

      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

  • @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?

  • @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!

  • @georggbess9547
    @georggbess9547 3 ปีที่แล้ว +1

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

    • @CodeVault
      @CodeVault  3 ปีที่แล้ว +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  3 ปีที่แล้ว +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.

  • @edsonbaptistafinda3312
    @edsonbaptistafinda3312 2 หลายเดือนก่อน

    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;
    }

  • @chnsnyz
    @chnsnyz 10 หลายเดือนก่อน

    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  9 หลายเดือนก่อน +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

  • @shaharrefaelshoshany9442
    @shaharrefaelshoshany9442 2 ปีที่แล้ว

    best content

  • @soniablanche5672
    @soniablanche5672 9 หลายเดือนก่อน

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

    • @CodeVault
      @CodeVault  9 หลายเดือนก่อน

      Usually they are the same size

  • @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.

  • @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

  • @abhaygaikwad6251
    @abhaygaikwad6251 2 ปีที่แล้ว

    understood

  • @MayankSharmaee23b045
    @MayankSharmaee23b045 5 หลายเดือนก่อน

    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  5 หลายเดือนก่อน

      There is no intrinsic wait in the loop

  • @Anonymous-nn5wn
    @Anonymous-nn5wn 2 ปีที่แล้ว +1

    Could you do the same using mutex In the critical section

    • @CodeVault
      @CodeVault  2 ปีที่แล้ว +1

      Yes, of course

  • @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

  • @ferxoorubio
    @ferxoorubio 3 ปีที่แล้ว +1

    Can u simply pass &primes[i] ?

    • @CodeVault
      @CodeVault  3 ปีที่แล้ว +1

      Yeah that should also work!

  • @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

  • @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

  • @balaganeshn4442
    @balaganeshn4442 2 ปีที่แล้ว

    how to get the proper order output ?

    • @CodeVault
      @CodeVault  2 ปีที่แล้ว +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)

  • @diogoferreira7396
    @diogoferreira7396 ปีที่แล้ว

    i love you so much

    • @CodeVault
      @CodeVault  11 หลายเดือนก่อน

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

  • @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;
      }

  • @throwaway8342
    @throwaway8342 ปีที่แล้ว +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

      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