0

I'm doing a monte Carlo simulation to calculate pi using threads, I believe the mass of my logic is correct. I just need to pass the correct value into the pthread create function under the C library i'm using, I just don't understand how fulfill the void function parameter that is required... any suggestions?

#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define Num_POINTS 10000
#define Num_Threads 4

unsigned int seed;


void *monte_carlo(void *t_ID);




long thread_points;
int total_hits;

pthread_mutex_t mutex;

void *monte_carlo(void *t_ID){

        float x,y;
        long k, hits;
        long my_id;
        my_id = (long)t_ID;


        seed = time(NULL) * (my_id + 1);

        hits = 0;
        for(k = 0; k < thread_points; k++){
                x = (float)rand_r(&seed)/(float)RAND_MAX * 2 - 1;
                y = (float)rand_r(&seed)/(float)RAND_MAX * 2 - 1;
                if (sqrt((x*x)+(y*y)) <=1){
                        hits = hits + 1;
                }
        }

        pthread_mutex_lock(&mutex);
        total_hits = total_hits + hits;
        pthread_mutex_unlock(&mutex);



}

void * test(void *total_hits) {
    printf("%d\n", total_hits);
    pthread_exit(NULL);
}
int main()
{
        struct timespec start, finish;
        double elapsed;

        clock_gettime(CLOCK_MONOTONIC, &start);

        pthread_t TID[Num_Threads]  ;
        float pi;
        srand(time(NULL));
        int i, j;
        int l;



        test(total_hits);
        for(i = 0; i < Num_Threads; i++){
        l = pthread_create(&TID[i], NULL, test, (void *)i);
        if (l){
        printf("ERROR");
        exit(-1);

      }

      }

      for(j=0;j<Num_Threads;j++){

      pthread_join(TID[i], NULL);
  }

    clock_gettime(CLOCK_MONOTONIC, &finish);

    elapsed = (finish.tv_sec - start.tv_sec);
    elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;

    printf( "Time: %lf\n", elapsed );


    pi = ((double)total_hits/(double)Num_POINTS)*4.0;          //p = 4(m/n)
    printf("Pi: %f\n", pi);
    return 0;
    pthread_exit(0);

}
  • `i` is `int`, but in the function you're treating it as `long` with `(long)t_ID`. They have to be the same type. – Barmar Apr 12 '22 at 01:01
  • Ah yes I didn't catch that. – Johnny Driscoll Apr 12 '22 at 01:02
  • Other than that, your approach is correct. – Barmar Apr 12 '22 at 01:03
  • Do I have to move my rand-r and pi calculations into a void function for it to work? – Johnny Driscoll Apr 12 '22 at 01:04
  • Where do you call `monte_carlo()`? You're using `test` as the thread function. – Barmar Apr 12 '22 at 01:06
  • Anyway, once you convert the parameter in the thread function, you use it normally. Nothing else needs to use `void`. That's only done for the main thread function to make it generic. – Barmar Apr 12 '22 at 01:07
  • whoops, sorry I posted the rendition where I was just testing the parameters a little. In my current code I'm passing the monte carlo function in and not "test" – Johnny Driscoll Apr 12 '22 at 01:09
  • Ok now I'm simply getting a warning with my last argument that I'm passing into pthread create should I use something different other than "(void *)i" – Johnny Driscoll Apr 12 '22 at 01:18
  • What's the warning? – Barmar Apr 12 '22 at 01:20
  • well after I changed it to a long it actually fixed that warning, but I still have a non-void function warning. I assume this is because of the main however even when I do a simple return 0 it still doesn't remove the warning. – Johnny Driscoll Apr 12 '22 at 01:23
  • Note that transferring an integer via a `void *` is implementation defined behaviour. It *might* work, or not, depending on the system. Using an intermediate cast to `(u)intptr_t` should make the operation fully defined. – Oka Apr 12 '22 at 01:24
  • @Oka I'm pretty sure POSIX requires it to work as expected so that code like this will work. POSIX has a number of requirements like this that go beyond what the C standard says is portable. – Barmar Apr 12 '22 at 01:24
  • I think that warning is because `monte_carlo` is declared to return `void*` but has no `return` statement that returns a value. Put `return NULL;` at the end. – Barmar Apr 12 '22 at 01:25
  • sweet, yes that fixed it. the pi calculation is still saying 0, if thats a logic error I can fix it but is it still most likely because of my pthread create parameters? – Johnny Driscoll Apr 12 '22 at 01:29
  • @Barmar I'm not so sure (see [here](https://stackoverflow.com/q/7822904/2505965)), but yes, it probably would work as expected. Messy details in any case. – Oka Apr 12 '22 at 01:43

0 Answers0