【问题标题】:C linux sem_wait doesn't work (sometimes) in threadsC linux sem_wait 在线程中(有时)不起作用
【发布时间】:2015-11-20 18:53:05
【问题描述】:

我只粘贴模型,这显示了问题。在函数中:
int get_random_prime(mpz_t number) 我得到了:sem_wait(&prime_count);,但它不能正常工作。即使信号量大于 0,它也会等待和等待。

#include<gmp.h>
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>

size_t number_of_cores=2;   
pthread_mutex_t mutex_queue;    
sem_t prime_count;              
sem_t threads_count;                    
size_t last_length=0;           
size_t prime_got=0;             
char manager_on=0;              

mpz_t prime;


get_random_odd(mpz_t output,size_t length){

    size_t i;
    size_t dev_random;
    int randomFile= open("/dev/urandom", O_RDONLY);

    read(randomFile,&dev_random,8);
    mpz_set_ui(output,dev_random);

    for(i=1;i<(length/64);i++){
        read(randomFile,&dev_random,8);
        mpz_mul_2exp (output,output, 64);
        mpz_add_ui(output,output,dev_random);
    }

    close(randomFile);

    mpz_setbit(output,length-1);
    mpz_setbit(output,0);
}

void* get_random_prime_thread(void* ptr_length){
    size_t result = 0;
    size_t i;
    size_t length = *((size_t*)ptr_length);
    mpz_t number;
    mpz_init(number);

    //do{
        get_random_odd(number, length);
        i=0;
    /*  do{
            result=miller_rabin_test(number);
            i++;
        }while(result==1 && i<prime_precision);*/
    //}while(result==0);

    pthread_mutex_lock(&mutex_queue);
    mpz_set(prime,number);
    pthread_mutex_unlock(&mutex_queue);

    sem_post(&prime_count);
    mpz_clear(number);  
    pthread_exit(NULL);

};

void* get_random_prime_manager_start(void* length){
    size_t i;
    size_t size=32;
    pthread_t *threads=malloc(sizeof(pthread_t)*size);
    manager_on =1;

    pthread_t rc;

    pthread_mutex_init(&mutex_queue,NULL);
    sem_init(&threads_count,0,number_of_cores);
    sem_init(&prime_count,0,0);

    i=-1;

    do{
        sem_wait(&threads_count);
        i++;
                printf("PROCES:%d\n",i);
        if(i>=size){
            threads=realloc(threads,size*2);
        }
        rc=pthread_create(&threads[i],NULL,get_random_prime_thread,length);
        if(rc){
            printf("%s\n",strerror(errno));
            pthread_exit((void*)-1);
        }
    }while(manager_on);

    for(i;i>0;i--){
        pthread_cancel(threads[i]);
    }

    free(threads);

    pthread_mutex_destroy(&mutex_queue);
    sem_destroy(&threads_count);
    sem_destroy(&prime_count);
    pthread_exit(NULL);
}

void* get_random_prime_manager_stop(){
    manager_on=0;
}

int get_random_prime(mpz_t number){

    sem_wait(&prime_count);
    printf("GET\n");
    pthread_mutex_lock(&mutex_queue);
    mpz_set(number,prime);
    pthread_mutex_unlock(&mutex_queue);
    sem_post(&threads_count);
    return 0;
};

int main(){
    mpz_init(prime);
    size_t rc;
    size_t length=1024;
    pthread_t thread;
    mpz_t p,q,n;
    mpz_init(p);
    mpz_init(q);
    mpz_init(n);

    size_t half_length=length/2;
    rc=pthread_create(&thread,NULL,get_random_prime_manager_start,(void*)&half_length); 
    if(rc){
        printf("%s\n",strerror(errno));
        return -1;
    }

    do{
        get_random_prime(p);
        get_random_prime(q);

        mpz_mul(n,p,q);
    }while( mpz_sizeinbase(n,2)==length);

    get_random_prime_manager_stop();

    mpz_clear(p);
    mpz_clear(q);
    mpz_clear(n);
}

线程是否可能等待尚未启动的信号量?

【问题讨论】:

  • 你在threads=realloc(threads,size*2);之后错过了size*=2;
  • @mch thx,你说得对,但它不能解决问题,因为如果它挂起,它会在前 2 个线程之后挂起
  • 你应该创建一个minimal reproducible example

标签: c linux multithreading semaphore


【解决方案1】:

在尝试使用任何信号量之前,您需要确保 sem_init 调用完成。最好的方法是正常调用get_random_prime_manager_start,让它初始化信号量,启动一个线程,然后返回。这样,您就可以确保管理器已充分启动,以便在函数返回时可以安全使用它。

【讨论】:

  • 变量manager_on在调用get_random_prime后变为0
  • 也许我不明白你的意思,但我在调用get_random_prime 后销毁了信号量我在我的问题中添加了一个函数来解释这一点。
  • 我是否可以尝试等待尚未启动的信号量?因为它有时会启动更快的等待?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
相关资源
最近更新 更多