Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vovk.doc
Скачиваний:
0
Добавлен:
27.12.2019
Размер:
456.19 Кб
Скачать

23.Синхронізація потоків за „приєднанням”. (взято из Кертона, изменяй, когда переписываешь)

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

pthread_join(pthread_t thread, void ** value_ptr)

Этой функции передаётся идентификатор потока, к которому вы желаете присоединиться и наобязательный аргумент value_ptr, который может быть использован для сохранения возвращаемого присоединяемым потоком значения (можно передать NULL)

Рассмотреть алгоритм выполнения данной синхронизации можно на конкретном примере. Предположим, что имеем графическую программу, выполняющую алгоритм трассировки луча. Каждая строка растра на экране зависит от содержимого основоной базы данных. Ключевым моментом здесь является то, что каждая строка растра не зависит от остальных. Это обстоятельство автоматически приводит к программированию данной задачи как многопоточной.

Const int num_cpu=4; //количество процессов;

int i;

pthread_t ptid[num_cpu];

for(i=0; i<num_cpu, i++)

pthread_create(&ptid[i], NULL, do_one, NULL);

for(i=0; i<num_cpu; i++)

pthread_join(ptid[i],(void) i);

void * do_one (void * a);

{ int b=(int) a;

int i;

for(i=0; i<n; i++) work(i+b*n);

}

Здесь главный поток присоединяет к себе запущенные потоки и ждет их окончание в любом порядке. Данный механизм работает даже в том случае, если потоки завершаются в обратном порядке. Например, последний завершил работу — это не окажет никакого воздействия на main(), который будет по-прежнему ждать завершения первого потока. Потом завершили работу третий и второй потоки. Когда завершится первый поток, цикл for просто «проскочит» уже завершённые потоки и завершиться. В этот момент мы будем знать, что вычислительные потоки синхронизованы, и теперь мы можем выводить результаты на отображение.

24. Синхронізація потоків за «бар'єром».

Этот метод синхронизации означает, что создается объект типа «барьер», преодолеть который можно только при «встрече у барьера» нескольких потоков. При этом потоки не обязаны быть завершенными – они просто ждут и, когда заданное число потоков достигнуто, они разблокируются.

«Барьер» создается с помощью функции:

#include <sync.h>

int barrier_init(barrier_t *barrier, const barrier_attr_t *attr, int count);

Эта функция создает объект типа «барьер» по преданному ей адресу, назначает атрибуты «барьера» и в переменной count – число потоков, которые должны встретиться у «барьера».

Каждый поток, который будет ждать у «барьера», должен вызвать функцию:

int barrier_wait(barrier_t *barrier);

После этого поток блокируется ОС до тех пор, пока не будет достигнуто число блокированных потоков, указанное в count. После того, как это число потоков будет достигнуто, все потоки разблокируются одновременно.

При синхронизации по «барьеру» потоки ожидают, пока их не наберется нужное число.

Пример:

#include <sync.h>

#include <stdio.h>

#include <time.h>

#include <sys\neutrino.h>

barrier_t barrier;

void *thread1(void *a){

time_t now; char buf[27]; time (&now);

printf(“Thread1 started at %s”, ctime_t(&now, buf));

sleep(10); //имитация работы

barrier_wait(&barrier);

time(&now);

printf(“Thread1: barrier passed at %s”, ctime_r(&now, buf));}

void *thread2(void *a){

… sleep(20); …}

main(){

time_t now; time (&now); char buf[27];

printf(“Main started at %s”, ctime_r(&now, buf));

barrier_init(&barrier, NULL, 3);

//запуск 2х потоков:

pthread_create(NULL, NULL,thread1,NULL);

pthread_create(NULL, NULL,thread2,NULL);

barrier_wait(&barrier); //ждем у барьера

time(&now);

printf(“Main passed barrier at %s”, ctime_r(&now, buf));}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]