Я пытался построить систему (в Linux) с имитацией времени выполнения, координируя потоки с семафорами, идея заключалась в том, чтобы сделать их все рабочие циклы одной секунды, чтобы иметь точную симуляцию, потоки должны ждать завершения каждого другого потока. его выполнение в текущую смоделированную секунду.
У меня была очень раздражающая утечка памяти, потому что основной поток завершил работу, не присоединившись к другим потокам (ошибка новичка), поэтому для ее решения я добавил инструкции pthread_join() для каждого потока, полагая, что они заканчивают свою работу, поскольку выполнение каждого потока находился внутри цикла while с глобальным условием для проверки, которое было изменено основным потоком перед завершением. К сожалению, даже при этом сейчас большинство выполнений программы зависает в ожидании завершения потока.
Мне нужно найти способ завершить выполнение каждого потока, даже игнорируя его полную работу, но убедившись, что соединение выполнено (и поэтому память освобождена).
Теперь я выкладываю компилируемый код с ошибкой, вы можете скомпилировать его с помощью gcc -o sample -pthread sample.c -lm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <math.h>
#define SIZE 100
#define READY 12345
#define END 99
#define TIME 3600
int *advicer;
int *td;
pthread_t *phones;
sem_t *counter;
int ready;
int end;
void cycle(int cycles){
int i,j,k;
for(i = 0; i < cycles; i++){
k = 1;
while(k){
k = 0;
for(j = 0; j < SIZE; j++){
if(advicer[j] == 0){
k = 1;
break;
}
}
}
for(j = 0; j < SIZE; j++){
advicer[j] = 0;
sem_post(&counter[j]);
}
}
}
void *do_something(void *td){
int t;
t = *((int *) td);
while(end != END){
if(end == END)
break;
t += t;
advicer[t] = 1;
sem_wait(&counter[t]);
}
pthread_exit(NULL);
}
void all_free(){
int i,j;
end = END;
printf("reach %d\n",end);
for(i = 0; i < SIZE; i++)
sem_post(&counter[i]);
printf("reach2\n");
for(i = 0; i < SIZE; i++){
pthread_join(phones[i],NULL);
}
free(phones);
printf("reach3\n");
for(i = 0; i < SIZE; i++)
sem_destroy(&counter[i]);
free(counter);
free(td);
free(advicer);
}
void main(){
int i,my_count;
counter = (sem_t *)malloc(sizeof(sem_t)*SIZE);
advicer = (int *)malloc(sizeof(int)*SIZE);
td = (int *)malloc(sizeof(int)*SIZE);
phones = (pthread_t *)malloc(sizeof(pthread_t)*SIZE);
for(i = 0; i < SIZE; i++){
sem_init(&counter[i], 0, 0);
advicer[i] = 0;
}
ready = READY;
my_count = 0;
end = 0;
for(i = 0; i < SIZE; i++){
td[i] = i;
pthread_create(&(phones[i]), NULL, do_something, (void *)(&td[i]));
}
printf("starting simulation\n");
while(my_count < TIME){
cycle(60);
printf("hello\n");
my_count += 60;
}
printf("simulation ended\n");
all_free();
}
do_something()
, то не потребуется много времени, чтобы получить полный, компилируемый набор исходных кодов C. Я не вижу проблемы в опубликованном коде, так что это может быть что-то, что еще не показано (конечно, я могу просто упустить проблему, которая есть...) - person Michael Burr   schedule 04.03.2012t += t;
вdo_something()
вызывает ошибку, не связанную с тем, чтоpthread_join()
никогда не возвращается (из-за ошибки «основной» цикл вmain()
никогда не заканчивается). Увеличениеt
таким образом приводит к тому, что потоки получают доступ за пределами конца массивовadvicer[]
иcounter[]
. Если я закомментирую эту строку, программа будет работать нормально в моих тестах - если вы закомментируете эту строку, вы все еще видите проблему? - person Michael Burr   schedule 08.03.2012