简体   繁体   中英

How can I multi thread my function? Using pthread

I've a function with complexity (n-1)! I would like to use multiple threads to calculate a length, then, if the length is lower, update the minimumLength value.

See my code (not the real one)

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#define N 10

struct params {
    int* minL_ptr;
    int** minLArray_ptr;
    int** numArray_ptr;
};

void *updateMin(void *void_param){
    struct params **params_ptr_ptr=(struct params **)(void_param);
    struct params *params_ptr=(struct params *)*params_ptr_ptr;
    int* minL_ptr=(int *)params_ptr->minL_ptr;
            printf("minL %d\n",*minL_ptr);

    int** minLArray_ptr=(int **)params_ptr->minLArray_ptr;
    int** numArray_ptr=(int **)params_ptr->numArray_ptr;

    int length=0;
    for(int i=0;i<N;i++)
        length+=(*numArray_ptr)[i]; // in my real code it's not as easy as that

    if(length<=*minL_ptr){
        *minL_ptr=length;
        for(int i=0;i<N;i++)
            (*minLArray_ptr)[i]=(*numArray_ptr)[i];
    }

return NULL;
}


int main(void){


    pthread_t thread[12];

    srand(time(NULL));

    int minL=50000;
    int *minL_arr=calloc(N,sizeof(int));

    struct params *parameters=malloc(sizeof(struct params));
    parameters->minL_ptr=&minL;
    parameters->minLArray_ptr=&minL_arr;

    for(int i=0;i<50000;i++) { // (n-1)! example
        int *numArray=malloc(N*sizeof(int));
        for(int j=0;j<N;j++)
            numArray[i]=rand()%1000; // generate random int array to sum later
        parameters->numArray_ptr=&numArray;


        pthread_create(&thread[i%11],NULL,updateMin,&parameters); // send parameters to a thread
    }
    for(int i=0;i<12;i++)
        pthread_join(thread[i],NULL);

    printf("Result : \n mL = %d\n",minL);
    for(int i=0;i<N;i++)
        printf("%d ",minL_arr[i]);

    return 0;
 }

So I have some segmentation error, I tried to print minL value each time updateMin is called, but at a time it shows 0 and then a segmentation error.

Tried valgrind, and saw some IO error.

==1546== Memcheck, a memory error detector
==1546== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1546== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==1546== Command: ./test
==1546== Parent PID: 62488
==1546== 
==1546== Thread 2:
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x400882: updateMin (main.c:26)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Thread 4:
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x58B2E07: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Use of uninitialised value of size 8
==1546==    at 0x58B249B: _itoa_word (_itoa.c:179)
==1546==    by 0x58B656C: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x58B24A5: _itoa_word (_itoa.c:179)
==1546==    by 0x58B656C: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x58B65B8: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x58B2ECF: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Conditional jump or move depends on uninitialised value(s)
==1546==    at 0x58B2F4F: vfprintf (vfprintf.c:1648)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)
==1546== 
==1546== Thread 1:
==1546== Invalid write of size 4
==1546==    at 0x4009A5: main (main.c:53)
==1546==  Address 0x5c16358 is 0 bytes after a block of size 40 alloc'd
==1546==    at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==1546==    by 0x400959: main (main.c:51)
==1546== 

valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 864, hi = 0.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

==1546==    at 0x3805022C: report_and_quit (m_libcassert.c:260)
==1546==    by 0x38050386: vgPlain_assert_fail (m_libcassert.c:340)
==1546==    by 0x3805C962: vgPlain_arena_malloc (m_mallocfree.c:301)
==1546==    by 0x38021374: vgMemCheck_new_block (mc_malloc_wrappers.c:377)
==1546==    by 0x380216AF: vgMemCheck_calloc (mc_malloc_wrappers.c:452)
==1546==    by 0x3809C522: vgPlain_scheduler (scheduler.c:1766)
==1546==    by 0x380AB4DC: run_a_thread_NORETURN (syswrap-linux.c:103)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==1546==    at 0x4C29590: calloc (vg_replace_malloc.c:618)
==1546==    by 0x4010F21: allocate_dtv (dl-tls.c:296)
==1546==    by 0x401162D: _dl_allocate_tls (dl-tls.c:460)
==1546==    by 0x4E3ABD6: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==1546==    by 0x400A0E: main (main.c:57)

Thread 2: status = VgTs_WaitSys
==1546==    at 0x595DFB9: __lll_unlock_wake_private (lowlevellock.S:341)
==1546==    by 0x58B76B9: _L_unlock_1050 (vfprintf.c:2333)
==1546==    by 0x58B27B2: vfprintf (vfprintf.c:2069)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 3: status = VgTs_WaitSys
==1546==    at 0x595DFB9: __lll_unlock_wake_private (lowlevellock.S:341)
==1546==    by 0x58B76B9: _L_unlock_1050 (vfprintf.c:2333)
==1546==    by 0x58B27B2: vfprintf (vfprintf.c:2069)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 4: status = VgTs_WaitSys
==1546==    at 0x595DF8B: __lll_lock_wait_private (lowlevellock.S:95)
==1546==    by 0x58B769E: _L_lock_976 (vfprintf.c:2333)
==1546==    by 0x58B2752: vfprintf (vfprintf.c:1325)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 5: status = VgTs_WaitSys
==1546==    at 0x595DFB9: __lll_unlock_wake_private (lowlevellock.S:341)
==1546==    by 0x58B76B9: _L_unlock_1050 (vfprintf.c:2333)
==1546==    by 0x58B27B2: vfprintf (vfprintf.c:2069)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 6: status = VgTs_WaitSys
==1546==    at 0x595DF8B: __lll_lock_wait_private (lowlevellock.S:95)
==1546==    by 0x58B769E: _L_lock_976 (vfprintf.c:2333)
==1546==    by 0x58B2752: vfprintf (vfprintf.c:1325)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 7: status = VgTs_WaitSys
==1546==    at 0x595DF8B: __lll_lock_wait_private (lowlevellock.S:95)
==1546==    by 0x58B769E: _L_lock_976 (vfprintf.c:2333)
==1546==    by 0x58B2752: vfprintf (vfprintf.c:1325)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)

Thread 8: status = VgTs_WaitSys
==1546==    at 0x595DF8B: __lll_lock_wait_private (lowlevellock.S:95)
==1546==    by 0x58B769E: _L_lock_976 (vfprintf.c:2333)
==1546==    by 0x58B2752: vfprintf (vfprintf.c:1325)
==1546==    by 0x58BC768: printf (printf.c:33)
==1546==    by 0x40082D: updateMin (main.c:17)
==1546==    by 0x4E3A061: start_thread (pthread_create.c:312)
==1546==    by 0x5951A3C: clone (clone.S:111)


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

Where do you think is the problem?

Probably not the only problem, but this is definitely not right;

for(int j=0;j<N;j++)
    numArray[i]=rand()%1000;   // looping j, indexing by i

You're looping i to 50000, so numArray which is 10 integers long will be written way out of bounds, giving all kinds of undefined behavior in the rest of the program.

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