UML диаграммы, используемые при описании параллельных задач:
Название | Описание |
---|---|
Диаграмма (видов) деятельности | Разновидность Диаграммы состояний, в которой большинство состояний - это виды деятельности, а большинство переходов активизируются при выполнении некоторого действия в исходных состояниях |
Диаграмма взаимодействия | Отображает взаимодействие между объектами. Взаимодействия описываются сообщениями, которыми они обмениваются. Выделяют диаграммы сотрудничества, диаграммы последовательностей и диаграммы (видов) деятельности |
Диаграммв (параллельных) состояний | Диаграмма показывает последовательность преобразований объекта в процессе его реакции на события. Особенность в том, что эти преобразования могут происходить одновременно |
Диаграмма последовательностей | Диаграмма взаимодействия, в которой отражается организация структуры объектов, принимающих или отправляющих сообщения (акцент на упорядочение во времени) |
Диаграмма сотрудничества | Диаграмма взаимодействия, в которой отображается организация структуры объектов, принимающих и отправляющих сообщения (акцент на структурной организации) |
Диаграмма развёрт-ия (внедрения) | Динамическая конфигурация узлов обработки, аппаратных средств и программных компонентов в системе |
Диаграмма компонентов | Диаграмма взаимодействия, в которой отображается организация физических модулей программного кода (пакетов) в системе и зависимости между ними |
Процессы
Выделяют системные и пользовательские. Пользовательские могут обращаться к системным для выполнения каких-либо действий, говорят, что он пребывает в привилегированном режиме (kernrel mode). При этом он не может быть выгружен другим пользовательским процессом.
Диаграмма состояний процесса:
Функции дробления процессов:
fork + execl
#include <unistd.h> #include <stdlib.h> int main(int argc, char * argv[]) { pid_t result = fork(); if(result == 0) { execlp("dig", "@server4ibm", "+short", "hoxnox1.otdel4.a", NULL); exit(EXIT_SUCCESS); } else { execlp("dig", "@server4ibm", "+short", "poma-k-n.otdel4.a", NULL); exit(EXIT_SUCCESS); } return 0; }
system Аналогична запуску fork + exec, но родительский процесс засыпает на время запуска оболчки с сыновним процессом. То есть родительский и сыновний процессы синхронны.
#include <stdlib.h> int main(int argc, char * argv[]) { system("dig @server4ibm +short hoxnox1.otdel4.a"); system("dig @server4ibm +short poma-k-n.otdel4.a"); return 0; }
posix_spawn В отличии от первых, позволяет * Игнорировать сыновним процессом сигналов, игнорируемых родительским. Или, напротив, устанавливать для действий по умолчанию * обмениваться дескрипторами файлов * установить для сыновнего процесса идентификатор группы * установить стратегию планирования сыновнего процесса отличной от стратегии родителя
#include <spawn.h> #include <stdio.h> int main(int argc, char * argv[]) { posix_spawnattr_t attr; posix_spawn_file_actions_t file_actions; pid_t pid; char* const args[] = {"dig", "@server4ibm", "+short", "hoxnox1.otdel4.a", NULL}; char* const args2[] = {"dig", "@server4ibm", "+short", "hoxnox1.otdel4.a", NULL}; char* const envs[] = {"PROCESSES=2", NULL}; int stat; posix_spawnattr_init(&attr); posix_spawn_file_actions_init(&file_actions); posix_spawnp(&pid, "dig", &file_actions, &attr, args, envs); posix_spawnp(&pid, "dig", &file_actions, &attr, args2, envs); wait(&stat); wait(&stat); return 0; }
Для того, чтобы заставить родительские процессы ждать в асинхронных вариантах, можно использовать фнкции wait и waitpid.
Ресурсы
Разделение ресурсов процессами можно изображать соответствующим графом. Точки внутри ресурсов обозначают количество ресурсов данного типа (например процессоры в многопроцессорной системе).
Функции по работе с ресурсами:
Лимитирование
struct rlimit { rlim_t rlim_cur; rlim_t rlim_max; }
- int setrlimit(int resource, const struct rlimit *rlp)
- int getrlimit(int resource, struct rlimit *rlp)
Использование
- int getrusage(int who, struct rusage *r_usage)
Способы реализации параллелизма
Потоки
Потоки во многом похожи на процессы. Главное отличие состоит в том, что каждый процесс имеет собственное адресное пространство. Если процесс создает множество потоков, то все они будут работать в одном адресном пространстве.
Потоки, в отличии от процессов равноправны и каждый поток может влиять на другие. В процессах же только родительский может влиять на сыновние.
Атрибуты потоков:
Модели функционирования потоков
Pthread
#include <pthread.h>
#include <stdio.h>
void *dig1(void *arg)
{
int n = *(int *)arg;
printf("thread A: %d * %d = %d\n", n, n, n*n);
return 0;
}
void *dig2(void *arg)
{
int n = *(int *)arg;
printf("thread B: %d + %d = %d\n", n, n, n+n);
return 0;
}
int main()
{
int N = 5;
pthread_t threadA, threadB;
pthread_create(&threadA, NULL, dig1, &N);
pthread_create(&threadB, NULL, dig2, &N);
pthread_join(threadA, NULL);
pthread_join(threadB, NULL);
return 0;
}
Атрибуты потока
- размер стека потока
- местоположение стека потока
- стратегия планирования, наследование и параметры
- тип потока: открепленный или присоединяемый
- область конструкции потока
Закрытие потока
Один поток может попытаться отменить другой вызовом pthread_cancel, но аннулируемый сам определяет когда ему это лучше сделать и делать ли вообще см. pthread_setcanceltype pthread_setcancelstate. Кроме того, существует определённый механизм отмены - должны быть вызваны функции заданные pthread_cleanup_push.
Соревнование потоков
На то в каком порядке потока будут выделяться ресурсы влияют 3 вещиЖ
- область конкуренции (pthread_attr_setscope)
- уровень системы
- уровень процесса
- стратегия планирования (pthread_attr_setinheritsched, pthread_attr_setshedpolicy)
- FIFO
- RR
- other
- Приоритет (pthread_attr_setshedparam)
Синхронизация
Типы синхронизации
- СС
- СФ
- ФС
- ФФ
Стратегии управления памятью
- exclusive read & exclusive write EREW
- concurrent read & exclusive write CREW
- exclusive read & concurrent write ERCW
- concurrent read & concurrent write CRCW
Семафоры
Мьютексный семафор
Функции pthread для работы с мьютексами имеют префикс pthread_mutex.
Мьютекс позволяет процессу или потоку при входе в критический участок заблокировать какой-либо объект (см. lock, timedlock, unlock, trylock, destroy).
Перед использованием мьютекс должен быть проинициализирован или значениями по умолчанию:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
или с помощью соответствующей структуры pthread_mutexattr_t.
Атрибуты
- закрытый/разделяемый (разделяемый может использоваться несколькими процессами) (pshared)
- блокированный/деблокированный
- предельный приоритет (proiceiling)
- протокол (protocol)
- тип (type)
Пример использования разделяемого мьютекса:
int result;
pthread_mutex_t mutex1;
pthread_mutexattr_t mutex_attr;
int main()
{
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mutex1, &mutex_attr);
if( (result = fork()) == 0 )
{ // сыновний процесс
pthread_mutex_lock(&mutex1);
// Критический раздел
pthread_mutex_unlock(&mutex1);
}
else
{ // родительский процесс
pthread_mutex_lock(&mutex1);
// Критический раздел
pthread_mutex_unlock(&mutex1);
}
return 0;
}
Блокировки на чтение и запись
Более интеллектуальный тип блокировки вместо одно операции блокирования имеется две:
- pthread_rwlock_rdlock()
- pthread_rwlock_wrlock()
Данные блокировки реализуют CREW стратегию управления. Один нюанс - при монопольной записи, запрещено какое-либо чтение.
Условная переменная
pthread_cond_t позволяет реализовать
- ожидание (pthread_cond_wait)
- ожидание с ограничением по времени (pthread_cond_timedwait)
- адресная сигнализация (pthread_cond_signal)
- всеобщая сигнализация (pthread_cond_broadcast)
Используют для управления отношениями синхронизацииша
Comments
comments powered by Disqus