Kod: Zaznacz cały
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
int ile_1;
int ile_2;
void blokuj()
{
sigset_t iset;
sigemptyset(&iset);
sigaddset(&iset, SIGINT); //dodanie ctrl+c do zestawu iset
sigaddset(&iset, SIGTSTP); //dodanie ctrl+z do zestawu iset
sigprocmask(SIG_BLOCK, &iset, NULL); //blokowanie zestawu sygnałów iset, dodatkowo nie przechowuje
//informacji o poprzednim zestawie (NULL)
}
void funkcjapotomka2(int nrsig, siginfo_t *info, void *ucontext_t)
{
printf("Rodzic odebral sygnal SIGUSR2 o nr: %d od procesu: %d\n", info->si_signo, info->si_pid);
ile_2++;
}
void funkcjapotomka(int nrsig, siginfo_t *info, void *ucontext_t)
{
printf("Rodzic odebral sygnal SIGUSR1 o nr: %d od procesu: %d\n", info->si_signo, info->si_pid);
ile_1++;
}
int main (int argc, char *argv[])
{
struct sigaction dlapierwszego;
struct sigaction dladrugiego;
pid_t main, pid1, pid2;
int czas;
czas = atoi(argv[1]);
main = getpid();
pid1=fork();
if(pid1==0)
{
while(1)
{
sleep(1);
kill(main, SIGUSR1); //wyslanie sygnalu
}
}
else
{
dlapierwszego.sa_flags = SA_SIGINFO;
dlapierwszego.sa_sigaction = (void *) funkcjapotomka;
sigaction(SIGUSR1, &dlapierwszego, NULL);
pid2=fork();
if(pid2==0)
{
while(1)
{
sleep(3);
kill(main, SIGUSR2);
}
}
else
{
dladrugiego.sa_flags = SA_SIGINFO;
dladrugiego.sa_sigaction = (void *) funkcjapotomka2;
sigaction(SIGUSR2, &dladrugiego, NULL);
}
}
while(czas)
{
sleep(1);
czas--;
if (czas == 0)
{
kill(SIGTERM, pid1);
kill(SIGTERM, pid2);
sleep(2);
printf("Jestem procesem o id: %d | wyslalem %d sygnalow\n", (int)pid1, ile_1);
printf("Jestem procesem o id: %d | wyslalem %d sygnalow\n", (int)pid2, ile_2);
}
}
return 0;
}
------------------------------------
Zauważyłem że zamiast czekać sekundę - sleep(1) - w pętli while należy użyć funkcji pause(), która usypia proces na czas dostarczenia sygnału. Jednak wynik nadal nie jest satysfakcjonujący (8:3).
-----------------------------------
Poprawiona wersja:
Kod: Zaznacz cały
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int pid1, pid2;
int ilosc = 0;
int flag1 =1;
int flag2 =1;
struct sigaction dlapierwszego, dladrugiego, dlatrzeciego;
void blokuj()
{
sigset_t iset;
sigemptyset(&iset);
sigaddset(&iset, SIGTSTP);
sigaddset(&iset, SIGINT);
sigprocmask(SIG_SETMASK, &iset, NULL);
}
void odbierz(int signum, siginfo_t *info)
{
if(signum == SIGUSR1) printf("Rodzic odebrał sygnal SIGUSR1 od procesu: %d\n",info->si_pid);
else if(signum == SIGUSR2) printf("Rodzic odebrał sygnal SIGUSR2 od procesu: %d\n",info->si_pid);
}
void obslugaterm(int signum, siginfo_t *info)
{
if(signum == SIGTERM)
{
printf("\nPotomek o id: %d, wyslal: %d sygnalow\n",getpid(),ilosc);
flag1=0;
flag2=0;
}
}
int main(int argc, char **argv)
{
dlapierwszego.sa_flags = SA_SIGINFO;
dlapierwszego.sa_sigaction = (void (*)(int, siginfo_t*, void*)) odbierz;
sigaction(SIGUSR1, &dlapierwszego, NULL );
sigaction(SIGUSR2, &dlapierwszego, NULL );
blokuj();
pid1 = fork();
if(!pid1)
{
blokuj();
dladrugiego.sa_flags = SA_SIGINFO;
dladrugiego.sa_sigaction = (void (*)(int, siginfo_t*, void*)) obslugaterm;
sigaction(SIGTERM, &dladrugiego, NULL );
while(flag1)
{
kill(getppid(), SIGUSR1);
ilosc++;
sleep(1);
}
exit(0);
}
pid2 = fork();
if(!pid2)
{
blokuj();
dlatrzeciego.sa_flags = SA_SIGINFO;
dlatrzeciego.sa_sigaction = (void (*)(int, siginfo_t*, void*)) obslugaterm;
sigaction(SIGTERM, &dlatrzeciego, NULL );
while(flag2)
{
kill(getppid(), SIGUSR2);
ilosc++;
sleep(3);
}
exit(0);
}
int czas = atoi(argv[1]);
while(czas)
{
sleep(1);
czas--;
}
kill(pid1, SIGTERM);
kill(pid2, SIGTERM);
int i;
for(i = 0; i < 2; i ++)
wait(NULL);
}