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

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

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

Β // для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ всСй Π³Ρ€ΡƒΠΏΠΏΡ‹ сигналов управлСния ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ

Β // Π΅Π΄ΠΈΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ, ΠΈΠ½Π°Ρ‡Π΅ всС Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΠΏΡ€ΠΎΡ‰Π΅.

Β struct sigaction act;

Β sigemptyset(&act.sa_mask);

Β act.sa_sigaction = handler;

Β act.sa_flags = SA_SIGINFO;

Β // создаСм Π³Ρ€ΡƒΠΏΠΏΡƒ ΠΎΠ΄Π½ΠΎΡ‚ΠΈΠΏΠ½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Β const int thrnum = 3;

Β for (int i = SIGRTMIN; i - SIGRTMIN < thrnum; i++) {

Β  sigset_t sig;

Β  sigemptyset(&sig);

Β  sigaddset(&sig, 1);

Β  // Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Π»:

Β  sigprocmask(SIG_BLOCK, &sig, NULL);

Β  if (sigaction(i, &act, NULL) < 0) perror("set signal handler: ");

Β  // для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π½ΠΎΠΌΠ΅Ρ€Π° сигнала ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ

Β  // Ρ‚Ρ€ΡŽΠΊ с ΠΏΠΎΠ΄ΠΌΠ΅Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°:

Β  pthread_create(NULL, NULL, threadfunc, (void*)(i));

Β }

Β // Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ Ρ†ΠΈΠΊΠ»ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

Β for (int i = 0; ; i++) {

Β  sleep(1);

Β  // посылку сигнала ΠΌΠΎΠΆΠ½ΠΎ (Ρ‚Π°ΠΊ Π΄Π°ΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Π΅Π΅)

Β  // ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

Β  // union sigval val;

Β  // val.sival_int = i;

Β  // sigqueue(getpid(), SIGRTMIN + i % thrnum, val);

Β  // Π½ΠΎ ΠΌΡ‹ ΡΠΎΠ·Π½Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ дСмонстрируСм ΠΈ ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΠΎΡΡ‚ΡŒ kill:

Β  kill(getpid(), SIGRTMIN + i % thrnum);

Β }

}

Π’ этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ цикличСски ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρƒ Π°ΠΊΡ‚ΠΈΠ²ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. Π’ΠΎΡ‚ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π²ΠΎΠ΄Π° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹:

SIG = 41; TID = 2

SIG = 42; TID = 3

SIG = 43; TID = 4

SIG = 41; TID = 2

SIG = 42; TID = 3

SIG = 43; TID = 4

SIG = 41; TID = 2

SIG = 42; TID = 3

SIG = 43; TID = 4

Часто приходится ΡΠ»Ρ‹ΡˆΠ°Ρ‚ΡŒ: Β«β€¦Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ сигнал всСм ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ, ΡƒΠ²Π΅Π΄ΠΎΠΌΠΈΡ‚ΡŒ всСх ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ потокС…», ΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ Π² Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ дСйствий понимаСтся модСль сигналов Π² ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ… ΠΏΡ€ΠΈ повСрхностном с Π½Π΅ΠΉ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠ»Π΅Π½ΠΈΠΈ. Иногда это прСдставляСтся ΠΎΡ‡Π΅Π½ΡŒ интСрСсной Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ, ΠΈ ΠΌΡ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ Ρ‚Π°ΠΊΡƒΡŽ схСму взаимодСйствия Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ( Ρ„Π°ΠΉΠ» s10.cc):

ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½Π°Ρ рСакция Π½Π° сигнал

#include <stdio.h>

#include <iostream.h>

#include <signal.h>

#include <unistd.h>

#include <pthread.h>

#include <sys/neutrino.h>

#include <vector>

static void handler(int signo, siginfo_t* info, void* context) {

Β cout << "SIG = " << signo << ", TID = " << pthread_self() << endl;

}

static void endhandler(int signo) {}

// сигнал, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΡŽΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΈ:

const int SIGNUM = SIGRTMIN;

sigset_t sig;

struct threcord {

Β int tid;

Β bool noblock;

};

static vector<threcord> tharray; // Π²Π΅ΠΊΡ‚ΠΎΡ€ состояний ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

void* threadfunc(void* data) {

Β // Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ всСх ΠΏΡ€ΠΎΡ‡ΠΈΡ… сигналов:

Β sigset_t sigall;

Β sigfillset(&sigall);

Β SignalProcmask(0, 0, SIG_BLOCK, &sigall, NULL);

Β // пСрСдСспСтчСризация для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ формирования Π²Π΅ΠΊΡ‚ΠΎΡ€Π°

Β sched_yield();

Β tharray[(int)data].noblock =

Β  (SignalProcmask(0, 0, SIG_UNBLOCK, &sig, NULL) != -1);

Β while (true) {

Β  pause();

Β  tharray[(int)data].noblock =

Β Β  !(SignalProcmask(0, 0, SIG_BLOCK, &sig, NULL) != 1);

Β  bool nolast = false;

Β  for (vector<threcord>::iterator i = tharray.begin();

Β  Β i != tharray.end(); i++)

Β Β  if (nolast = i->noblock) break;

Β Β // ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ пСрСсылка сигнала ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ

Β  if (nolast) kill(getpid(), SIGNUM);

Β  // ... ΠΊΠΎΠ³Π΄Π° ΠΏΠ΅Ρ€Π΅ΡΡ‹Π»Π°Ρ‚ΡŒ большС Π½Π΅ΠΊΠΎΠΌΡƒ -

Β  // пСрСинициализация масок

Β  else

Β Β  for (vector<threcord>::iterator i = tharray.begin();

Β Β  Β i != tharray.end(); i++)

Β Β Β Β i->noblock = (SignalProcmask(0, i->tid, SIG_UNBLOCK, &sig, NULL) != -1);

Β }

}