Вход/Регистрация
QNX/UNIX: Анатомия параллелизма
вернуться

Цилюрик Олег Иванович

Шрифт:

Кроме основной нашей цели это приложение дополнительно демонстрирует:

• Практическое использование принудительного завершения (отмены) потоков «извне» с управлением состоянием завершаемости потоков и расстановкой точек отмены, о чем мы уже говорили ранее.

• Использование атомарных (непрерываемых) операций (например,

atomic_add_value
), о которых мы будем говорить чуть позже.

• Использование реентерабельных форм функций стандартной библиотеки, безопасных в многопоточной среде (

rand_r
вместо
rand
).

Один производитель — T потребителей

#include <stdlib.h>

#include <stdio.h>

#include <iostream.h>

#include <unistd.h>

#include <pthread.h>

#include <errno.h>

#include <semaphore.h>

#include <atomic.h>

const int D = 10;

unsigned int T = 2;

static sem_t sem;

pthread_t* tid;

void* writer(void* data) {

unsigned long i = (int)(data); // общий размер выборки

unsigned int s = 1;

while (i-- > 0) {

delay((long)rand_r(&s) * D / RAND_MAX + 1);

sem_post(&sem); // объект данных произведен

}

for (i = 0; i < T; i++) pthread_cancel(tid[i + 1]);

return NULL;

}

static char *str; // строка результирующей диагностики

static volatile unsigned ind = 0;

void* reader(void*) {

char tid[8];

sprintf(tid, "%X", pthread_self);

unsigned int s = rand;

pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

while(true) {

sem_wait(&sem); // получен объект данных

str[atomic_add_value(&ind, 1)] = *tid;

pthread_testcancel;

delay((long)rand_r(&s) * D * T / RAND_MAX + 1);

}

return NULL;

}

int main(int argc, char *argv[]) {

unsigned long N = 1000;

int opt, val;

while ((opt = getopt(argc, argv, "n:t:")) != -1) {

switch(opt) {

case 'n':

if (sscanf(optarg, "%i", &val) != 1)

cout << "parse command line error" << endl, exit(EXIT_FAILURE);

if (val > 0) N = val;

break;

case 't':

if (sscanf(optarg, "%i", &val) != 1)

cout << "parse command line error" << endl, exit(EXIT_FAILURE);

if (val > 0) T = val;

break;

default:

exit(EXIT_FAILURE);

}

}

str = new char[N + 1];

tid = new pthread_t[T + 1];

if (sem_init(&sem, 0, 0))

perror("semaphore init"), exit(EXIT_FAILURE);

if (pthread_create(tid, NULL, writer, (void*)N) >= EOK)

perror("writer create error"), exit(EXIT_FAILURE);

for (int i = 0; i < T; i++)

if (pthread_create(tid + i + 1, NULL, reader, NULL) != EOK)

  • Читать дальше
  • 1
  • ...
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: