Kniga-Online.club
» » » » QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович

QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович

Читать бесплатно QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович. Жанр: Интернет год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

static bool debug = false;

static char* str;

static volatile int ind = 0;

void* threadfunc(void* data) {

 pthread_barrier_wait(&bstart);

 unsigned long i = 0;

 char tid[8];

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

 uint64_t t = 0, t1;

 while (i++ != N) {

  t1 = ClockCycles();

  pthread_mutex_lock(&mutex);

  if (debug) str[ind++] = *tid;

  pthread_mutex_unlock(&mutex);

  t += ClockCycles() - t1;

  sched_yield();

 }

 cout << pthread_self() << "t: cycles - "

  << t << ", on mutex - " << t / N << endl;

 return NULL;

}

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

 int opt, val;

 while ((opt = getopt(argc, argv, "n,v")) != -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 'v':

   debug = true;

   break;

  default:

   exit(EXIT_FAILURE);

  }

 }

 if (debug) str = new char[2 * N + 1];

 const int T = 2;

 pthread_t tid[T];

 if (pthread_barrier_init(&bstart, NULL, T) != EOK)

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

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

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

   perror("thread create"), exit(EXIT_FAILURE);

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

  pthread_join(tid[i], NULL);

 if (debug) {

  str[ind] = '';

  cout << str << endl;

  delete [] str;

 }

 exit(EXIT_SUCCESS);

}

Результаты выполнения этого теста:

# sy20m -n100000

3       : cycles - 14644442, on mutex - 146

2       : cycles - 14614219; on mutex - 146

# sy20m -n1000000

3       : cycles - 146505047; on mutex - 146

2       : cycles - 146388673; on mutex - 146

Модифицируем программу, используя вместо мьютекса неименованный бинарный семафор. Для того чтобы не загромождать текст практически тем же кодом, перечислим только необходимые при этом изменения ( файл sy20s.cc):

1. Вместо мьютекса объявляем неименованный семафор, а статическая инициализация мьютекса заменяется на оператор (в теле главной программы) динамической инициализации семафора с присвоением ему начального значения 1:

static sem_t sem;

...

if (sem_init(&sem, 0, 1) != 0)

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

2. Функция потока принимает вид:

void* threadfunc(void* data) {

 ...

 while (i++ != N) {

  t1 = ClockCycles();

  sem_wait(&sem);

  if (debug) str[ind++] = *tid;

  sem_post(&sem);

  t += ClockCycles() - t1;

  sched_yield();

 }

 ...

}

В результате исполнения на этот раз мы получим:

# sy20s -n100000

3       : cycles - 87048886; on semaphore - 870

2       : cycles - 87077787; on semaphore - 870

# sy20s -n1000000

3       : cycles - 869638168; on semaphore — 869

2       : cycles - 868725494, on semaphore - 868

Делаем последнюю модификацию в этой группе тестов, теперь используем специфику именованного семафора ( файл sy20n.cc):

1. Вместо оператора динамической инициализации неименованного семафора мы теперь должны создать именованный семафор:

static sem_t* sem;

...

const char semname[] = "/duble";

if ((sem = sem_open(semname, O_CREAT, S_IRWX0, 1)) == SEM_FAILED)

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

Примечание

Последний оператор заслуживает отдельного комментария. Техническая документация утверждает, что функция sem_open(), нормально возвращающая указатель созданного дескриптора семафора типа sem_t, в случае ошибки возвращает -1 (так было записано и в самых ранних редакциях POSIX). Но использование конструкции вида:

if (sem_open( ... ) == -1)

просто вызовет синтаксическую ошибку (несоответствие типов) и не пройдет компиляцию! Естественнее было бы для такой функции возвращать NULLв случае ошибки, но... так определено в POSIX. Кроме того, во многих реализациях UNIX определяется константа:

#define SEM_FAILED ((sem_t*)(-1))

В документации QNX она нигде не упоминается, но, как мы видим, она определена, и все прекрасно работает!

Перейти на страницу:

Цилюрик Олег Иванович читать все книги автора по порядку

Цилюрик Олег Иванович - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


QNX/UNIX: Анатомия параллелизма отзывы

Отзывы читателей о книге QNX/UNIX: Анатомия параллелизма, автор: Цилюрик Олег Иванович. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*