У меня есть пара вопросов. Это моя первая настоящая попытка создания многопоточной программы.
ПРИМЕЧАНИЕ - полная программа находится внизу страницы
(для компиляции используйте
g++ -pthread -o <executable file name> <sourcefile>.cpp -fpermissive
)
Я скомпилировал его, используя 64-битную версию Ubuntu Studio 10.10.
Самая большая проблема этой программы в том, что она вызывает ошибку сегментации.
Кажется, это вызвано строкой, которую я прокомментировал в int main (). Если я прокомментирую эту строку, это не даст мне ошибку ошибки сегментации.
Вот только int main () для удобства:
int main()
{
pthread_attr_t attr;
pthread_t threads[30];
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&direction_mutex, NULL);
pthread_mutex_init(&arrive_mutex,NULL);
pthread_cond_init (&count_threshold, NULL);
pthread_cond_init(&arrive_done, NULL);
/*
For portability, explicitly create threads in a joinable state
I'll take your word for it on that one.
*/
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for( int x = 0 ; x < 30 ; x++)
{
long random = rand();
int direction;
if (random < RAND_MAX/2)
{
direction = 0;
}
else
{
direction = 1;
}
directions[x] = direction;
printf("%d",direction);
}
printf("\n");
currdir = directions[0];
for(int j = 0 ; j < 30 ; j++)
{
if(j != 0)
{
pthread_cond_wait(&arrive_done, NULL); // THIS line of code is what is causing the problem
}
pthread_create(&threads[j], &attr, OneCar, (void *)&Thread_IDs[j]);
}
/* Wait for all threads to complete */
for (j = 0; j < 30; j++)
{
pthread_join(threads[j], NULL);
}
printf("test\n");
/* Clean up and exit */
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&direction_mutex);
pthread_cond_destroy(&count_threshold);
pthread_exit (NULL);
}
Без этой строки программа запускается, но проблема в том, что она выглядит довольно случайно в порядке потоков.
Я пытался использовать эту блокировку мьютекса, чтобы не позволять int main () запускать новый поток до тех пор, пока не завершится последний поток, поскольку предполагается, что в этой программе потоки выполняются в порядке FIFO.
Без этого кода поведение меняется.
Большую часть времени он начинается с потока 0, затем переходит к потоку 3,4, иногда даже 5, прежде чем вернуться к потоку 1.
Иногда он начинается в потоке 3, затем переходит в поток 4, затем поток 0 ... Я не могу понять, почему он это делает.
Это каждый раз другая последовательность выполнения потоков, но она никогда не бывает 0,1,2,3,4, как должно быть
Вот вывод с закомментированной строкой:
*** Output of program with "pthread_cond_wait(&arrive_done, NULL);" commented out:
101110010101011111010001000010
ArriveBridge(): Car 1 goes accross the bridge
ExitBridge(): car 1 has left the bridge
Arrivebridge(): Thead 0 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 0 goes accross the bridge
ExitBridge(): car 0 has left the bridge
Arrivebridge(): Thead 5 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 5 goes accross the bridge
ExitBridge(): car 5 has left the bridge
Arrivebridge(): Thead 3 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 3 goes accross the bridge
ExitBridge(): car 3 has left the bridge
ArriveBridge(): Car 2 goes accross the bridge
ExitBridge(): car 2 has left the bridge
ArriveBridge(): Car 4 goes accross the bridge
ExitBridge(): car 4 has left the bridge
Arrivebridge(): Thead 6 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 6 goes accross the bridge
ExitBridge(): car 6 has left the bridge
Arrivebridge(): Thead 7 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 7 goes accross the bridge
ExitBridge(): car 7 has left the bridge
Arrivebridge(): Thead 8 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 8 goes accross the bridge
ExitBridge(): car 8 has left the bridge
Arrivebridge(): Thead 9 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 9 goes accross the bridge
ExitBridge(): car 9 has left the bridge
Arrivebridge(): Thead 10 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 10 goes accross the bridge
ExitBridge(): car 10 has left the bridge
Arrivebridge(): Thead 11 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 11 goes accross the bridge
ExitBridge(): car 11 has left the bridge
ArriveBridge(): Car 13 goes accross the bridge
ExitBridge(): car 13 has left the bridge
Arrivebridge(): Thead 12 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 12 goes accross the bridge
ExitBridge(): car 12 has left the bridge
Arrivebridge(): Thead 14 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 14 goes accross the bridge
ExitBridge(): car 14 has left the bridge
ArriveBridge(): Car 15 goes accross the bridge
ExitBridge(): car 15 has left the bridge
ArriveBridge(): Car 16 goes accross the bridge
ExitBridge(): car 16 has left the bridge
Arrivebridge(): Thead 18 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 18 goes accross the bridge
ExitBridge(): car 18 has left the bridge
Arrivebridge(): Thead 17 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 17 goes accross the bridge
ExitBridge(): car 17 has left the bridge
ArriveBridge(): Car 19 goes accross the bridge
ExitBridge(): car 19 has left the bridge
Arrivebridge(): Thead 21 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 21 goes accross the bridge
ExitBridge(): car 21 has left the bridge
ArriveBridge(): Car 20 goes accross the bridge
ExitBridge(): car 20 has left the bridge
ArriveBridge(): Car 22 goes accross the bridge
ExitBridge(): car 22 has left the bridge
Arrivebridge(): Thead 23 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 23 goes accross the bridge
ExitBridge(): car 23 has left the bridge
Arrivebridge(): Thead 24 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 24 goes accross the bridge
ExitBridge(): car 24 has left the bridge
ArriveBridge(): Car 25 goes accross the bridge
ExitBridge(): car 25 has left the bridge
ArriveBridge(): Car 26 goes accross the bridge
ExitBridge(): car 26 has left the bridge
ArriveBridge(): Car 27 goes accross the bridge
ExitBridge(): car 27 has left the bridge
ArriveBridge(): Car 29 goes accross the bridge
ExitBridge(): car 29 has left the bridge
Arrivebridge(): Thead 28 is trying to go in the opposite direction, it must wait for traffic to clear
ArriveBridge(): Car 28 goes accross the bridge
ExitBridge(): car 28 has left the bridge
test
Это вывод БЕЗ этой закомментированной строки
****output of program before commenting pthread_cond_wait(&arrive_done, NULL); out:
101110010101011111010001000010
Segmentation fault
Как вы можете видеть, он почти сразу перестает работать до создания каких-либо потоков.
Другая вещь, которую я пытался улучшить, состоит в том, что моя последовательность нулей и единиц не очень случайна. Есть ли лучший способ получения случайных чисел? Оно не должно быть чрезвычайно случайным, но эта последовательность всегда одинакова.
Спасибо за ваше время