Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 64

Автор Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ ОлСг Π˜Π²Π°Π½ΠΎΠ²ΠΈΡ‡

2. Ѐункция ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π²ΠΈΠ΄ (Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ

sem
, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ случая, вСдь Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ это ΡƒΠΆΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ‚ΠΈΠΏΠ°
sem_t
):

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();

Β }

Β ...

}

3.Β Π’Π΅ΠΏΠ΅Ρ€ΡŒ особоС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ созданию, Π½ΠΎ ΠΈ Π»ΠΈΠΊΠ²ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ сСмафора (Ρ‚Π°ΠΊΠΎΠΉ сСмафор ΠΈΠΌΠ΅Π΅Ρ‚ врСмя ΠΆΠΈΠ·Π½ΠΈ ядра систСмы ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ своС сущСствованиС ΠΈ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ нашСго прилоТСния):

sem_close(sem);

sem_unlink(semname);

Запустим ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ -n, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ обСспСчит достаточноС врСмя Π΅Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Ρ‹. ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΎΠ±ΡΡƒΠΆΠ΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹, посмотрим ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сСмафора Π½Π° пространство Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… ΠΈΠΌΠ΅Π½ систСмы Π²ΠΎ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ прилоТСния:

# ls -l /dev/sem

total 1

n------r-Ρ… 1 root root 1 Feb 10 18.56 duble

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

# nice -n-19 sy20n -n100000

3Β Β Β Β Β  : cycles - 1453746002, on semaphore - 14537

2Β Β Β Β Β Β : cycles - 1454203573, on semaphore - 14542

НаконСц, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ количСствСнному Π°Π½Π°Π»ΠΈΠ·Ρƒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Ρ†ΠΈΡ„Ρ€:

β€’Β ΠŸΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹Β β€” ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΈ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафоры,Β β€” каТущиСся Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд сходными, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ для своСго обслуТивания Π² эквивалСнтных условиях ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π·Π°Ρ‚Ρ€Π°Ρ‚, Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π°Π΄ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ: 140 – 870 – 14500 процСссорных Ρ†ΠΈΠΊΠ»ΠΎΠ² соотвСтствСнно, Ρ‡Ρ‚ΠΎ соотносится ΠΊΠ°ΠΊ 1:6,2:104.

β€’Β Π’Π°ΠΊ ΠΆΠ΅ Ρ€Π°Π΄ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΈ ΠΈΡ… характСристики доступа: ΠΈΠ·Π½ΡƒΡ‚Ρ€ΠΈ процСсса (ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ Π²Π»Π°Π΄Π΅Π΅Ρ‚ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠΌ), ΠΈΠ· внСшнСго процСсса, ΠΈΠ· процСсса, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ Π½Π° ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌ сСтСвом узлС… Π’ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ рассматривали ΠΊΠ°ΠΊ «характСристики Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈΒ» ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ катСгориям: процСсса (process-persistent), ядра (kernel-persistent) ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы (filesystem-persistent).

β€’Β Π£ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° всСгда Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ-Π²Π»Π°Π΄Π΅Π»Π΅Ρ†, ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π² дальнСйшСм. ИмСнно поэтому ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ синхронизации Π² смыслС разграничСния Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ доступак Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρƒ ΠΊΠΎΠ΄Π° β€” ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ часто Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ критичСской сСкциСй ΠΊΠΎΠ΄Π°. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сСмафора Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹ΡˆΠ΅: ΠΏΡ€ΠΈ возмоТности (ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда) Π΅Π³ΠΎ примСнСния Π² Ρ‚ΠΎΠΌ контСкстС, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΡƒΠΆΠ½ΠΎ Π»ΠΈ это Π΄Π΅Π»Π°Ρ‚ΡŒ?), ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ ΠΈ для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² смыслС ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ†ΠΈΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈΠΈΡ… взаимодСйствия Π² качСствС элСмСнта, ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ порядком выполнСния. ПокаТСм это Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅. Для этого Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ трансформируСм ΠΊΠΎΠ΄ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ тСста для сСмафора ( Ρ„Π°ΠΉΠ» sy21.cc):

Бинхронизация ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² сСмафорами

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <inttypes.h>

#include <iostream.h>

#include <unistd.h>

#include <pthread.h>

#include <errno.h>

#include <semaphore.h>

unsigned long N = 1000;

unsigned int T = 2;

static sem_t* sem;

static bool debug = false;

static char* str; // строка диагностики

static volatile int ind = 0;

uint64_t *t;

void* threadfunc(void* data) {

Β unsigned long i = 0;

Β char tid[8];

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

Β // врСмСнная ΠΌΠ΅Ρ‚ΠΊΠ° Π½Π°Ρ‡Π°Π»Π° Π²ΠΎ всСх ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ… устанавливаСтся

Β // Π½Π° врСмя достиТСния этой Ρ‚ΠΎΡ‡ΠΊΠΈ Π² послСднСм (Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌ) ΠΏΠΎΡ‚ΠΎΠΊΠ΅

Β if ((int)data == T - 1) {

  uint64_t с = ClockCycles();

Β  for (int i = 0; i < T; i++ ) t[i] = c;

Β }

Β // Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ Ρ†ΠΈΠΊΠ» ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π·Π° счСт синхронизации

Β while (i++ < N) {

Β  sem_wait(sem + (int)data);

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

Β  sem_post(sem + ((int)data +1) % T);

Β }

Β t[(int)data] = ClockCycles() - t[(int)data];

Β return NULL;

}

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

Β int opt, val;

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

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

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

Β Β  if (val > 0) T = val;

Β Β  break;