Β // Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π²ΡΠ΅ΠΉ Π³ΡΡΠΏΠΏΡ ΡΠΈΠ³Π½Π°Π»ΠΎΠ² ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ
Β // Π΅Π΄ΠΈΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΡΠ΅Π°ΠΊΡΠΈΠΈ, ΠΈΠ½Π°ΡΠ΅ Π²ΡΠ΅ Π±ΡΠ»ΠΎ Π±Ρ Π³ΠΎΡΠ°Π·Π΄ΠΎ ΠΏΡΠΎΡΠ΅.
Β 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);
Β }
}