我如何多线程我的功能?使用pthread

时间:2014-03-23 19:07:35

标签: c multithreading pthreads

我有一个复杂的功能(n-1)! 我想使用多个线程来计算长度,然后,如果长度较低,则更新minimumLength值。

查看我的代码(不是真实代码)

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

所以我有一些分段错误,我每次调用updateMin时都尝试打印minL值,但是一次显示0然后是分段错误。

尝试了valgrind,并看到了一些IO错误。

==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.

您认为问题在哪里?

1 个答案:

答案 0 :(得分:0)

可能不是唯一的问题,但这绝对不对;

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

你正在将i循环到50000,所以{10}整数的numArray将被写出越界,在程序的其余部分给出各种未定义的行为。