2016-06-26 11 views
1

Просто новичок в потоках, я просто выполняю задачу, которая включает в себя эти 2 потока.c - работает 2 потока параллельно с общей переменной

#include <stdio.h> 
#include <pthread.h> 

int count = 0; 

void waitFor(unsigned int secs) 
{ 
    unsigned int retTime = time(0) + secs; 
    while(time(0) < retTime); 
} 

void func1(void * args) 
{ 
    printf("In func1 ...\n"); 
    long i = 0; 
    while(1){ 
     i++; 
     if(count == 1) 
      break; 
    } 
    printf("The total number counted is: %ld \n", i); 
    count = 0; 
    i = 0; 
} 

void func2(void * args) 
{ 
    printf("In func2 ...\n"); 
    waitFor(3); 
    count = 1; 
} 


int main() 
{ 
    pthread_t th1, th2; 

    int j = 0; 
    while(j++ < 4){ 
     printf("\nRound:\t%d\n", j); 

     pthread_create(&th1, NULL, (void*)func1,NULL); 
     pthread_create(&th2, NULL, (void*)func2, NULL); 

     pthread_join(th1,NULL); 
     pthread_join(th2,NULL); 
     waitFor(3); 
    } 

    return 0; 
} 

Я читал различные ссылки и мое понимание pthread_join() означает, что если есть 2 или более потоки, то они будут ждать одну нити, чтобы закончить его выполнение, а затем следующий будет приступить к выполнению и так на.

Но когда я запускаю эту программу, выполняется момент pthread_join (th1), оба потока создаются и исполняются «одновременно». Как это происходит? Выход:

Round: 1 
In func2 ... 
In func1 ... 
The total number counted is: 897651254 

Round: 2 
In func1 ... 
In func2 ... 
The total number counted is: 1051386065 

........ 

Моя цель состоит в том, чтобы запустить эти 2 темы параллельно. На данный момент объединение похоже на это; или я где-то ошибаюсь?

И я читал, что использование volatile не является предпочтительным для потоков в C. Так можно ли использовать счет как сигнал от потока 2 к 1?

+0

Где вы читали «, если есть 2 или больше потоков, то они будут ждать, пока один поток завершит выполнение, а затем следующий начнет выполнение "? Pthread_join просто ждет тех потоков, которые вы дали в качестве аргумента для завершения. Что заставляет вас думать, что ваши ступени были созданы, когда вы вызвали pthread_join? Ваши потоки были созданы и запущены с помощью pthread_create. –

+3

Необходимо обеспечить одновременный доступ для чтения/записи к общим переменным ('count' здесь). Обычно это делается с использованием мьютекса. См. Функции 'pthread_mutex _ *()' на них. – alk

+0

@alk, если я заблокирую счет в func2, не будет ли весь мой func1 остановлен, пока func2 не разблокирует счет? или заявления до «count» в func1 выполняются и ждут, пока func2 не разблокирует его? то это означает, что нет права параллелизма? – vinwin

ответ

2

Цитата:

мое понимание pthread_join() означает, что если есть 2 или более потоков, то они будут ждать одну нить, чтобы закончить его выполнение, а затем следующий будет приступить к выполнению и так далее

Это неверно. Соединение просто означает, что процесс ждет, пока поток не завершится.

Сообщений:

момент pthread_join (Th1) выполняется, оба потока создаются и выполняются 'одновременно'.

Это неверно. Потоки создаются и запускаются при вызове pthread_create Примечание: К start Я имею в виду, что они готовы к выполнению. Тем не менее, именно ОС решает, когда они действительно выполняются, поэтому может потребоваться некоторое время, прежде чем они будут выполнены.

Чтобы поделиться count между двумя потоками, вы можете использовать мьютексы.

int count = 0; 
pthread_mutex_t lock; 

count При обращении вы должны сначала заблокировать мьютекс, чтение/запись переменной и разблокировать мьютекс.

Пример:

pthread_mutex_lock(&lock); 
count = 1; 
pthread_mutex_unlock(&lock); 

Пример:

pthread_mutex_lock(&lock); 
if(count == 1) 
{ 
    pthread_mutex_unlock(&lock); 
    break; 
} 
pthread_mutex_unlock(&lock); 

И main вам необходимо инициализировать семафор, как:

pthread_mutex_init(&lock,NULL); 
+0

Я знаю, что потоки начинают выполняться в тот момент, когда мы делаем pthread_create. Означает ли это параллельное выселение? И когда я пытаюсь без pthread_join, мой поток 2 даже не запускается. Зачем? – vinwin

+0

@ infoseeker - да, параллельно. Но значение параллели может отличаться от системы к системе. Простые одноядерные процессоры просто используют совместное использование времени, в то время как многоядерные процессоры могут запускать потоки по-настоящему параллельно. – 4386427

+1

@infoseeker Цитата: 'без 'pthread_join', мой поток 2 даже не запускается. Почему? «Я не могу знать, не имея подробностей о вашей системе. Догадка может заключаться в том, что 'main' завершен до того, как' threads' фактически выполняется. В любом случае требуется соединение, так как вам нужно дождаться окончания потоков – 4386427