Только один из нескольких потоков записывает

#c #pthreads #mutex

#c #pthreads #мьютекс

Вопрос:

У меня есть задача создать программу, подобную StarCraft, с несколькими pthreads в качестве рабочих.

Итак, у меня есть несколько pthreads, которые выполняют следующую функцию:

 void* scv(int num){
    int minerals_carried = 0;
    while(map_minerals_remaining>0){
        minerals_carried = 0;
        for(int i = 0; i<number_of_fields; i  ){
            if(fields[i].minerals != 0 amp;amp; minerals_carried == 0){
                if(pthread_mutex_trylock(amp;fields[i].mutex)==0){
                
                    sleep(1);
                    // mine returns int
                    minerals_carried = mine(amp;fields[i]);
                    printf("SCV%d is carrying %d minerals from field %dn",num,minerals_carried,i);
                    
                    if(pthread_mutex_unlock(amp;fields[i].mutex)!=0){
                        perror("pthread_mutex_unlock");
                        return NULL;
                    }
                }else{
                    perror("pthread_mutex_trylock");
                    return NULL;
                
                }
            }
            
        }
        
    }
    return NULL;
}
 

Я создаю 5 pthreads, и все они создаются правильно, но только первый выводится, как и предполагалось, а все остальные, похоже, ничего не делают. Есть идеи, почему это может быть?

РЕДАКТИРОВАТЬ: меня попросили показать, как я инициализировал number_of_fields и поля, и это все: сначала я объявляю их глобальными

 typedef struct Mineral_Field_t{
    pthread_mutex_t mutex;
    int minerals;

}Mineral_Field;

Mineral_Field* fields;
int number_of_fields = 2;
 

И тогда у меня есть следующий фрагмент кода в начале основной функции:

 if(argv[1] != NULL){
        number_of_fields = atoi(argv[1]);
    }
    fields = malloc(number_of_fields*sizeof(Mineral_Field));
 

Комментарии:

1. Можете ли вы показать, как вы инициализируете number_of_fields и поля? Вы объявили их как глобальные

2. Отредактировано, теперь вы должны видеть, что я делаю.

3. Вы уверены, что все потоки запущены? Потоки, которые не могут получить блокировку, должны сообщать об ошибке, pthread_mutex_trylock поскольку вы не блокируете.

4. О боже, спасибо, я все еще изучаю этот материал, и я забыл, что если мьютекс заблокирован, он все равно возвращает значение ошибки. Я удалил возвращаемый NULL; часть, и теперь все работает так, как задумано.

5. Вы можете ответить на свой собственный вопрос (если Barmar пройдет) вместо редактирования заголовка, это не так глупо. Я также проголосовал за хорошую дань уважения starcraft 😉