繁体   English   中英

为什么当我使用互斥变量时它没有正确锁定代码? 随时 function 给我一个不同的答案

[英]Why when I use a mutex variable it didn't lock the code correctly? anytime the function return me a different answers

所有包含和全局变量:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <sys/sysinfo.h>

pthread_mutex_t sum_lock = PTHREAD_MUTEX_INITIALIZER;
long sum = 0;
long primeCounter = 0;

我想知道为什么互斥锁没有锁定这两个变量,每次编译这段代码并运行它后,我都会得到不同的答案,这让我很抓狂我试图将互斥锁的块更改为其他地方,但仍然如此不工作。 这是解决问题的主要代码:

    void *main_routine(void *context){
    int processorsNumber = 10;
    struct readThreadParams *param = context;
    //init rundom generator

    int random;
    srand(param->randomPivot);
    //generate random numbers
    for (int i = 0; i < param->numOfRandomNumbers / processorsNumber; i++){
        random = rand();
        if (isPrime(random)){
            pthread_mutex_lock(&sum_lock);
            sum = sum + random;  // this is one of the variable.
            primeCounter++; // this is the second varaible
            pthread_mutex_unlock(&sum_lock);
        }
    }

    return NULL;
}

这是调用线程的主要内容:

    int main(int argc, char *argv[]){
    if (argc != 3){
        printf("Too few arguments ");
        printf("USAGE: ./primeCalc <prime pivot> <num of random numbers>");
        exit(0);
    }

    int i = 0;
    struct readThreadParams readParams;
    readParams.randomPivot = atoi(argv[1]);
    readParams.numOfRandomNumbers = atoi(argv[2]);
    int processorsNumber = 10;
    pthread_t *th = malloc(sizeof(pthread_t) * processorsNumber);

    for (i = 0; i < processorsNumber; i++){
        if (pthread_create(&th[i], NULL, &main_routine, &readParams) != 0){  
        return 1;
      }
    }

    for (i = 0; i < processorsNumber; i++){
        if (pthread_join(th[i], NULL) != 0){
            return 1;
       }
    }


    pthread_mutex_destroy(&sum_lock);
    //keep the out format as this!!
    printf("%ld,%ld\n", sum, primeCounter);
    exit(0);
}

randsrand function 使用内部 state,因此不可重入。 这意味着您的每个线程在调用srandrand时会相互干扰。

您想改用带有rand_r参数的 rand_r 。 这样每个线程都可以维护自己的 rng state。

void *main_routine(void *context){
    int processorsNumber = 10;
    struct readThreadParams *param = context;
    //init rundom generator

    unsigned int state = param->randomPivot;
    int random;
    //generate random numbers
    for (int i = 0; i < param->numOfRandomNumbers / processorsNumber; i++){
        random = rand_r(&state);
        if (isPrime(random)){
            pthread_mutex_lock(&sum_lock);
            sum = sum + random;  // this is one of the variable.
            primeCounter++; // this is the second varaible
            pthread_mutex_unlock(&sum_lock);
        }
    }

    return NULL;
}

首先,不保证rand()是线程安全的:“不需要 rand function 来避免与其他对伪随机序列生成函数的调用发生数据竞争......”

二、 srand(param->randomPivot); 在每个线程中都会破坏程序在给定相同种子的情况下产生相同结果的能力。

当任何一个线程调用srand()时,您不知道与调用srand()为随机数生成器或调用rand()获取随机数的所有其他线程相关的情况何时发生。

您需要调用srand()一次,可能在启动任何其他调用rand()的线程之前在主线程中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM