C,在循环中初始化的pthreads尽管有互斥锁,但不会正确执行已分配的函数

时间:2016-08-01 03:47:39

标签: c pthreads mutex pthread-key-create

我在调试我的C程序时遇到问题,其目标是创建5个线程,并让每个线程处理长度为10的数组的2个大小的块。目标是获取该数组的总和。我的实际程序比这更简单,因为它需要动态数组大小和线程数,但我尝试将其简化为这个简单的问题,但它仍然不起作用。

即,

array = {1 2 3 4 5 6 7 8 9 10}

然后thread1在数组[0]和数组[1]

上工作

和thread2适用于数组[2]和数组[3]

等...

thread5适用于数组[8]和数组[9]

然而,当我运行我的代码时,即使使用互斥锁,我也会得到奇怪的结果。

例如,这是我运行此程序时的结果之一。

Thread #1 adding 3 to 0 New sum: 3
Thread #1 adding 4 to 3 New sum: 7
Thread #2 adding 5 to 7 New sum: 12
Thread #2 adding 6 to 12        New sum: 18
Thread #3 adding 7 to 18        New sum: 25
Thread #3 adding 8 to 25        New sum: 33
Thread #4 adding 9 to 33        New sum: 42
Thread #4 adding 9 to 42        New sum: 51
Thread #4 adding 10 to 51       New sum: 61
Thread #4 adding 10 to 61       New sum: 71
Sum: 71

首先,为什么前3行的“新总和”之前没有标签? (请参阅我的printf登录calculate_sum函数)。更重要的是,为什么thread0永远不会执行它的工作,为什么线程4执行两次?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef struct {
    int start, end, thread_number;
    int *data;
} Func_args;

static pthread_mutex_t mutex;
static int sum = 0;

void *calculate_sum(void *args) {

    int *arr = ((Func_args *)args)->data;
    int i = ((Func_args *)args)->start;
    int end = ((Func_args *)args)->end;
    int t_id = ((Func_args *)args)->thread_number;

    while (i < end) {
        pthread_mutex_lock(&mutex);
        printf("Thread #%d adding %d to %d\t", t_id, arr[i], sum);
        sum += arr[i++];
        printf("New sum: %d\n", sum);
        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

#define NUM_THREAD 5
#define ARRAY_LEN 10

int main(int argc, char **argv) {

    int array[ARRAY_LEN] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    pthread_t tid[NUM_THREAD];
    int i, pos = 0;

    pthread_mutex_init(&mutex, NULL);

    for (i = 0; i < NUM_THREAD; i++) {
        Func_args args;
        args.data = array;
        args.thread_number = i;
        args.start = pos;
        pos += 2;
        args.end = pos;
        pthread_create(&tid[i], NULL, calculate_sum, &args);
    }

    for (i = 0; i < NUM_THREAD; i++)
        pthread_join(tid[i], NULL);

    pthread_mutex_destroy(&mutex);
    printf("Sum: %d\n", sum);

    return 0;
}

1 个答案:

答案 0 :(得分:4)

您正在向每个线程传递指向可能在线程启动之前被销毁的对象的指针。

passportInit: require('passport').initialize(), passportSession: require('passport').session(), order: [ 'startRequestTimer', 'cookieParser', 'session', 'passportInit', // <===== passportInit 'passportSession', // <===== passportSession 'bodyParser', 'handleBodyParserError', 'compress', 'methodOverride', 'poweredBy', '$custom', 'router', 'www', 'favicon', '404', '500' ] 是本地的,所以当程序退出它声明的作用域时(即在args循环体的末尾)它会被销毁。

线程可能需要一些时间才能启动,所以如果线程在此之后启动,它将访问一个被破坏的对象 - 实际上,内存将被重用来存储下一个线程的值。

您可以通过使用for动态分配线程数据来修复它(并在线程中记住malloc或者如果pthread_create失败)。