2016-03-06 3 views
0

Проблема с следующей программой заключается в том, что основной поток заканчивается перед тем, как другие потоки получают возможность отображать их результаты. Другая проблема заключается в том, что отображение потоков не в порядке.Проблемы с программой Threading

Выход должен быть:

This is thread 0. 
This is thread 1. 
This is thread 2. etc. 

код:

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <time.h> 
void *text(void *arg); 
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads 
int num = 0; 
int main() 
{ 
int i; 
pthread_t tid[7]; 
// Initialize random number generator 
time_t seconds; 
time(&seconds); 
srand((unsigned int) seconds); 
// Create our threads 
for (i = 0; i < 7; i++) 
pthread_create(&tid[i], NULL, text, (void*)code[i]); 
// Exit main 
return 0; 
} 
void *text(void *arg) 
{ 
long n = (long)arg; 
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep 
while (num != n) {} // Busy wait used to wait for our turn 
num++; // Let next thread go 
sleep(rand_sec); // Sleep for random amount of time 
printf("This is thread %d.\n", n); 
// Exit thread 
pthread_exit(0); 
} 

Может кто-нибудь помочь с помощью мьютекса, чтобы устранить проблему синхронизации?

+0

Ваше требование к сериализации - это как просить вас, чтобы новый автомобиль был оснащен квадратными колесами, и, во всяком случае, мьютекс является неподходящим механизмом для этого. –

+0

Вы можете использовать барьеры для синхронизации всех потоков, которые устраняют проблему уничтожения потоков. Кроме того, нет никакого известного способа последовательного выравнивания потоков. В первую очередь это убивает цель нитей. Вы должны явно использовать разделяемую память для сигнальных потоков для сериализации последовательности печати. – jada12276

+0

По сути, вы убиваете любое преимущество многопоточности, которое вы можете использовать, применяя мьютекс и синхронизацию. Обычно он будет медленнее, чем его однопоточное приложение. Что касается второй проблемы выхода приложения перед тем, как заканчивается любой поток, вы можете использовать соединение, чтобы дождаться завершения всех потоков до выхода. – Saleem

ответ

4

Вы можете использовать pthread_join, чтобы сделать вашу процедуру main подождать, пока ваши другие потоки не закончатся, например.

int main() 
{ 
int i; 
pthread_t tid[7]; 
// Initialize random number generator 
time_t seconds; 
time(&seconds); 
srand((unsigned int) seconds); 
// Create our threads 
for (i = 0; i < 7; i++) 
    pthread_create(&tid[i], NULL, text, (void*)code[i]); 
for(i = 0; i < 7; i++) 
    pthread_join(tid[i], NULL); 
// Exit main 
return 0; 
} 

Кроме того, ваш код, который ждет num быть идентификатор потока может иметь некоторые проблемы при запуске поворота оптимизаций на. Ваш переменная num должно быть объявлено volatile, если она распределяется между потоками, например, так:

volatile int num; 

Тем не менее, занято ожиданием на num как так очень, очень неэффективны. Вы должны рассмотреть возможность использования переменных условий для уведомления потоков при изменении num, чтобы они могли проверить, является ли это их очередь один раз, а затем спать, если нет. Посмотрите на все функции pthread_cond_* для получения дополнительной информации.

+2

['volatile' не для многопоточности] (http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming). Вы должны использовать подходящий тип данных атоматики, например [C11 atomics] (http://en.cppreference.com/w/c/atomic). – ComicSansMS

Смежные вопросы