2015-10-29 2 views
1

Я хотел создать программу, которая записывает нечетные и четные числа от 1 до 100 с двумя функциями, первая функция печатает первые 5 нечетных чисел, вторая функция печатает первые 5 четных чисел, и снова мы возврат к первой функции для печати вторых 5 нечетных чисел и т. д. В этой программе я хотел чередовать только потоки 2, но я не могу найти решение. Вот мой код, в этом коде я создал 40 threads. Кто-нибудь знает, как чередовать 2 потока и найти тот же результат.Альтернатива между двумя потоками

#include<stdio.h> 
#include<pthread.h> 
pthread_t tid[40]; 
int pair=2; 
int impair=1 ; 
pthread_mutex_t lock; 

void* genpair(void *arg) 
{ 
    pthread_mutex_lock(&lock); 
    int i = 0; 
    for (i=0 ; i<5 ; i++,pair+=2) 
    { 
     printf("%d ",pair) ; 
    } 
printf(" ");  
pthread_mutex_unlock(&lock); 

    return NULL; 
} 
void* genimpair(void *arg) 
{ 
    pthread_mutex_lock(&lock); 
    int i = 0; 
    for (i=0 ; i<5 ; i++,impair+=2) 
    { 
     printf("%d ",impair) ; 
    } 
printf(" ");  
pthread_mutex_unlock(&lock); 

    return NULL; 
} 

int main(void) 
{ 
    int i = 0; 
    int j=0 ; 
    int err; 

    if (pthread_mutex_init(&lock, NULL) != 0) 
    { 
     printf("\n mutex init failed\n"); 
     return 1; 
    } 

    for(j=0 ; j<20 ; j+=2) 
    { 
     pthread_create(&(tid[j]), NULL, &genpair, NULL); 
     pthread_create(&(tid[j+1]), NULL, &genimpair, NULL); 
     pthread_join(tid[j], NULL); 
     pthread_join(tid[j+1], NULL);   
    } 

    pthread_mutex_destroy(&lock); 

    return 0; 
} 
+0

Пожалуйста, описать текущее поведение вашей программы. Но для начала поставьте 'printf (" \ n ")' перед 'pthread_mutex_unlock', чтобы очистить буферизованный вывод, чтобы он появился на stdout. – kaylum

+0

Нет смысла использовать потоки для вашей задачи. – nwp

+0

@nwp Существует, если это учебное упражнение. Или если это MCVE, полученный из более крупной программы. – kaylum

ответ

-1

Вы должны использовать 2 различных семафор и ваш код будет как этот

//Thread pair 
{ 
    pthread_mutex_lock(&pairLock) 
    //Do pair job 
    pthread_mutex_unlock(&impairLock) 
} 

//Threa impair 
{ 
    pthread_mutex_lock(&impairLock) 
    //Do impair job 
    pthread_mutex_unlock(&pairLock) 
} 

Мьютексы из исходной нити должна начинаться с 1 (разблокированным), а другой на 0 (запертом)

Редактирование: использование одного и того же мьютекса для всех ваших потоков позволяет только одному потоку выполнять свою работу, но не форсирует какой-либо порядок или альтернативу (зависит от системного планировщика). В вашем случае genimpair может выполняться первым, если планировщик так говорит, но он не будет прерван genpair, в следующем цикле он может быть того же порядка или не

+0

Я все еще не вижу, как я могу чередовать эти 2 функции n раз только с использованием 2 потоков. – starter

+0

Начать каждый поток, затем «блокировать» и «разблокировать» соответствующий мьютекс, сколько раз вам нужно печатать все нужные вам номера. Подобно 'for() {lock(); работа(); unlock();} ' –

+1

Ваше решение не может работать, потому что два потока могут одновременно выполнять свою работу! Первый приобретает 'pairLock' и второй' impairLock', это два разных замка! –

1

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

// thread1 
do { 
    lock(m); 
    while (turn==0) cond_wait(m); // release the key if not my turn, retry until my turn 
    do my job; 
    turn = 0;      // give hand to the other 
    cond_broadcast(m);   // awake threads waiting for key (blocked in lock or cond_wait) 
    unlock(m);     // release the lock 
} while(); 

// thread2 
do { 
    lock(m); 
    while (turn==1) cond_wait(m); 
    do my job; 
    turn = 1; 
    cond_broadcast(m); 
    unlock(m); 
} while(); 

Вы также можете использовать два семафора за ту же работу ...

+0

Это ожидание! –

+0

Определенно нет! cond_wait - это блокирующий вызов. –

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