我必须发送信号p1 - > p2 - > p3 - > p1 ...以便更改共享文件的值。然而p3 - > p1不工作(p1没有捕获信号)。我把睡眠放在每次转换之间做出时间差异但是idk有什么不对。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
void sig_usr (int signo)
{
printf("%d\n",getpid());
// longjmp(jumpbuffer,1);
}
int main(int argc, char **argv)
{
signal(SIGUSR1, sig_usr);
jmp_buf jumpbuffer;
pid_t next,ppid,granmaduh;
granmaduh = getpid();
if ((next = fork()) <0 )
{
fprintf(stderr, "fork() error");
exit(1);
}
else if (next == 0 )
{
next = fork();
if (next >0)
{
sleep(6);
}
else
{
next = granmaduh;
sleep(10);
}
}
sleep(2);
printf("%d\n",next);
//setjmp(jumpbuffer);
kill(next, SIGUSR1);
exit(1);
}
答案 0 :(得分:0)
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
#include <errno.h>
static void signal_handler(int);
int i, pid1, pid2,pid3, status;
int main( int argc, char *argv[], char *env[] )
{
int exit_status;
if( signal( SIGUSR1, signal_handler) == SIG_ERR )
{
printf("Pærent: Unable to create handler for SIGUSR1\n");
}
// if( signal( SIGUSR2, signal_handler) == SIG_ERR )
// {
// printf("Pærent: Unable to create handler for SIGUSR2\n");
// }
printf( "Parent pid = %d\n", pid1=getpid() );
if( (pid2 = fork()) == 0 )
{
printf( "Child pid = %d\n", getpid() );
//printf( "Child: %d sending parent SIGUSR1\n", getpid() ); //kill( pid1, SIGUSR1 );
if( (pid3 = fork()) == 0 )
{
printf( "GranChild pid = %d\n", getpid() );
printf( "Child: %d sending parent SIGUSR1\n", getpid() ); kill( pid2, SIGUSR1 );
}
for( ;; ); /* loop forever */
}
else
{
/*
* This waits for ANY child to die. It doesn't matter if the child
* dies normally or from a signal. The satus information is then
* stored in the status integer.
*
* If you want to wait on a particular process use waitpid():
* waitpid( childPID, &status, 0 );
* is the common usage.
*
* Solaris acts weirdly when a signal is given to the parent process.
* Therefore we place the wait() inside a while loop so that wait()
* will not return before the child has died.
*/
/* while( (wait( &status ) == -1) && (errno == EINTR) ) {} */
wait(&status);
/*
* The information in status is *NOT* the return code!! To make use
* of the information we must macros to extract the needed
* information.
*/
/* WIFEXITED() determines if the process exited normally (returned a
* number). This can be done through a return or exit()
*/
if( WIFEXITED( status ) )
{
/*
* Now we know the process exited properly so we can get the
* return value
*
* Note that WEXITSTATUS only retuns the lower 8 bits! That means
* that if we ever expect a negative number then we have to count
* the 8th bit as a sign bit.
*/
exit_status = WEXITSTATUS( status );
/*
* Since we expect negative numbers...
*
* If the exit_status is greater than 2^7 (128), thæn the eigth bit
* is a 1, so we subtract 2^8 (256) from it to make it look like
* a negative number.
*/
if( exit_status > 128 )
{
exit_status -= 256;
}
printf( "Child return - %d\n", WEXITSTATUS( status ) );
}
else
{
/* Well it didn't exit properly. Was it a signal? */
if( WIFSIGNALED( status ) )
{
/*
* Yes. A signal killed the child process. Now we can extract
* the signal information from status
*/
printf( "Child died on signal - %d\n", WTERMSIG( status ));
}
}
/*
* There are two other macros most UNIXes use. They are:
* WIFSTOPPED() and WSTOPSIG(). See the man pages on the dells for
* more information.
*
* To wait on a particular pid - see waitpid()
*/
}
return 0;
}
static void signal_handler(int signo)
{
/* signo contains the signal number that was received */
switch( signo )
{
/* Signal is a SIGUSR1 */
case SIGUSR1:
printf( "Process %d: received SIGUSR1 \n", getpid() );
if(pid1==getpid()) /* it is the parent */
{
printf( "Process %d is passing SIGUSR1 to %d...\n", getpid(),pid2 );
kill( pid2, SIGUSR1 );
}
else if(pid2==getpid()) /* it is the child */
{
printf( "Process %d is passing SIGUSR2 to itself...\n", getpid());
kill(getpid(), SIGUSR2);
}
else
{
printf( "Process %d is passing SIGUSR2 to itself...\n", getpid());
kill(pid3, SIGUSR2);
}
break;
/* It's a SIGUSR2 */
case SIGUSR2:
printf( "Process %d: received SIGUSR2 \n", getpid() );
if(pid1==getpid())
{
printf( "Process %d is passing SIGUSR2 to %d...\n", getpid(),pid2 );
kill( pid2, SIGUSR2 );
}
else if(pid2==getpid())/* it is the child */
{
printf( "Process %d is passing SIGUSR2 to %d...\n", getpid(),pid3 );
kill(pid3, SIGINT);
}
else /* it is the child */
{
printf( "Process %d is passing SIGUSR2 to %d...\n", getpid() );
kill(getpid(), SIGINT);
}
break;
default:
break;
}
return;
}