#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 😉