Processes & Signals

 

vProcess in Memory

 

 

As a process executes, it changes state

§  new:  The process is being created

§  ready:  The process is waiting to be assigned to a processor

§  running:  Instructions are being executed

§  waiting:  The process is waiting for some event to occur

§  terminated:  The process has finished execution

Diagram of Process State

 

 

Process Control Block (PCB

Information associated with each process

 

 

CPU Switch from Process to Process

 

Process Scheduling Queues

§  Job queue – set of all processes in the system

§  Ready queue – set of all processes residing in main memory, ready and waiting to execute

§  Device queues – set of processes waiting for an I/O device

Processes migrate among the various queues

 

Representation of Process Scheduling

 

Schedulers

§  Long-term scheduler (or job scheduler) – selects which processes should be in the ready queue

§  Short-term scheduler  (or CPU scheduler) – selects which process should be allocated the CPU

Ø Short-term scheduler is invoked very frequently (milliseconds) Þ (must be fast)

Ø Long-term scheduler is invoked very infrequently (seconds, minutes) Þ (may be slow)

Ø The long-term scheduler controls the degree of multiprogramming

Ø Processes can be described as either:

o   I/O-bound process – spends more time doing I/O than computations, many short CPU bursts

o   CPU-bound process – spends more time doing computations; few very long CPU bursts

Context Switch

§  When CPU switches to another process, the system must save the state of the old process and

load the saved state for the new process via a context switch

§  Context of a process represented in the PCB

§  Context-switch time is an overhead; the system does no useful work while switching

 

 


vProcess Creation

·       Parent process create children processes,

which, in turn create other processes, forming a tree of processes

·       Generally, process identified and managed via a process identifier (pid)

·       Execution

§  Parent and children execute concurrently

§  Parent may waits until children terminate

 

·       Address space

§  Child duplicate of parent

§  Child may load new program.

 

·       UNIX examples

§  fork system call creates new process

§  exec system call used after a fork to replace the process’ memory with a new program

 

EXAMPLE:

newproc-posix.c

int main()

{

pid_t  pid, pid2;

    pid = fork();

    if (pid == 0) { // child process

         printf(“%d %d”, getpid(), getppid());

         execlp("/bin/ls", "ls", NULL);

    }

    else {          // parent process

        pid2=wait (NULL);

         printf ("%d %d %d", pid2, getpid(), getppid());

         exit(0);

    }

}

 

«   To execute:

 

% newproc-posix

 

EXAMPLE:

newproc.py

#! /usr/bin/env python
import sys
import os

childpid = os.fork()
if childpid == 0:
    print("I am child")
    os.execlp("/bin/date","date");
    os.exit(0)
else:
    os.wait()
    print("I am the parent of: ", childpid)

«   To execute:

 

% newproc.py

 

 


v   Interprocess Communication

§  Processes within a system may be independent or cooperating

§  Cooperating process can affect or be affected by other processes, including sharing data

§  Reasons for cooperating processes:

ü Information sharing

ü Computation speedup

ü Modularity

ü Convenience      

§  Cooperating processes need InterProcess Communication (IPC)

§  Examples of IPC

ü Shared memory

ü Message passing

Producer-Consumer Problem

Paradigm for cooperating processes,

Producer process produces information that is consumed by a Consumer process

§  unbounded-buffer places no practical limit on the size of the buffer

§  bounded-buffer assumes that there is a fixed buffer size

 

Bounded-Buffer – Shared-Memory Solution

Shared data:

 

#define BUFFER_SIZE 10

 

typedef struct {

  . . .

} item;

 

item buffer[BUFFER_SIZE];

int in = 0;

int out = 0;

 

Producer:

 

while (true) { 

       while ((( (in + 1) % BUFFER_SIZE)  == out)

         ;   /* do nothing -- no free buffers */

       /* Produce an item */

        buffer[in] = item;

        in = (in + 1) % BUFFER_SIZE;

}

 

Consumer:

 

while (true) {

        while (in == out)

          ; /* do nothing -- nothing to consume */

         /* Consume an item */

         item = buffer[out];

         out = (out + 1) % BUFFER_SIZE;

    }

 

 

ü This solution is correct, but can only use BUFFER_SIZE - 1  elements

 

 

Interprocess Communication – Message Passing

·       IPC facility provides two operations:

ü send (message) – message size fixed or variable

ü receive (message)

 

·       If P and Q wish to communicate, they need to:

ü establish a communication link between them

ü exchange messages via send/receive

Direct Communication

Processes must name each other explicitly:

·       send (P, message) – send a message to process P

·       receive (Q, message) – receive a message from process Q

Indirect Communication

Messages are directed and received from mailboxes (also referred to as ports)

·       Each mailbox has a unique id

·       Processes can communicate only if they share a mailbox

Synchronization

Message passing may be either blocking or non-blocking

·       Blocking is considered synchronous

ü Blocking send has the sender block until the message is received

ü Blocking receive has the receiver block until a message is available

 

·       Non-blocking is considered asynchronous

ü Non-blocking send has the sender send the message and continue

ü Non-blocking receive has the receiver receive a valid message or null

 

 


vShared Memory

·       Process first creates shared memory segment:

Segment  _id = shmget (IPC_PRIVATE, size, S_IRUSR | S_IWUSR);

 

·       Process wanting access to that shared memory must attach to it:

sharedmemory = (char *) shmat (id, NULL, 0);

 

·       The process could write/read to/from the shared memory:

sprintf (sharedmemory, "Writing to shared memory");

 

printf("%s", sharedmemory);

 

·       When done a process can detach the shared memory from its address space:

shmdt (sharedmemory);

 

EXAMPLES:

shm-fork-posix.c

 

int  main()

{

        pid_t           pid;

        int             segment_id;

        char           *shared_memory;

        const int       segment_size = 4096;

 

       

        segment_id = shmget(IPC_PRIVATE, segment_size, S_IRUSR | S_IWUSR);

        shared_memory = (char *) shmat(segment_id, NULL, 0);

 

       pid = fork();

 

       if (pid == 0) {         /* child process */

               

                sprintf(shared_memory, "I love my parents");

 

       } else {                /* parent process */

               sleep(1);

               printf("Parent Got: %s\n", shared_memory);

                if (shmdt(shared_memory) == -1) {

                        fprintf(stderr, "Unable to detach\n");

                }

                shmctl(segment_id, IPC_RMID, NULL);

                return 0;

       }

}

     }

 

«   To execute:

 

% shm-fork-posix

 

Shared/NonShared Example:

 

shmfork.c:

 

int
main()
{
   int    segment_id = shmget(IPC_PRIVATE, sizeof(int), S_IRUSR | S_IWUSR);
   int    *sharedVar = (int *) shmat(segment_id, NULL, 0);
   int    *nonsharedVar = (int *) malloc(sizeof(int));


    sharedVar[0] = 0;
    nonsharedVar[0] = 0;

   if (fork() == 0) {
      sharedVar[0]=getpid();
      nonsharedVar[0]=getpid();
      printf("\nChild: shared %d, nonshared %d\n",sharedVar[0],nonsharedVar[0]);
      exit(0);
   }
   wait(NULL);
   printf("Parent: shared %d, nonshared %d\n\n", sharedVar[0], nonsharedVar[0]);
}

 

«   To execute:

 

% shmfork

 

 

 


vClient-Server Communication

Sockets

·       A socket is defined as an endpoint for communication

·       Is bind to of IP address (e.g., 128.82.4.98) and port (e.g., 10117).

·       Communication is between a pair of sockets

EXAMPLE:

DateServer.java

public class DateServer

{

    public static void main(String[] args)  {

         try {

             ServerSocket sock = new ServerSocket(10117);

             // now listen for connections

             while (true) {

                 Socket client = sock.accept();                 

                 PrintWriter pout = new PrintWriter(client.getOutputStream(), true);

 

                 // write the Date to the socket

                 pout.println(new java.util.Date().toString());

 

                 // close the socket and resume listening for more connections

                 client.close();

             }

         }

         catch (IOException ioe) {

                 System.err.println(ioe);

         }

    }

}

DateClient.java

 

public class DateClient

{

    public static void main(String[] args)  {

         try {

         // this could be changed to an IP name or address other than the localhost

             Socket sock = new Socket("127.0.0.1",10117);

             InputStream in = sock.getInputStream();

             BufferedReader bin = new BufferedReader(new InputStreamReader(in));

             String line;

             while( (line = bin.readLine()) != null)

                 System.out.println(line);         

             sock.close();

         }

         catch (IOException ioe) {

                 System.err.println(ioe);

         }

}

 

 

«   To execute:

 

% java   DateServer

 

    In another window at the same host:

 

% java   DateClient

 

DateServer.c

int main(void)

{

        int             len, listenfd, connfd;

        struct sockaddr_in servaddr, cliaddr;

        char            buff[512];

        time_t          ticks;

 

        listenfd = socket (AF_INET, SOCK_STREAM, 0);

 

        bzero(&servaddr, sizeof(servaddr));

        servaddr.sin_family = AF_INET;

        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

        servaddr.sin_port = htons(10117);

 

        bind (listenfd, (SA *) & servaddr, sizeof(servaddr));

 

        listen(listenfd, 0);

 

        for (;;) {

                len = sizeof(cliaddr);

                connfd = accept (listenfd, (SA *) & cliaddr, &len);

 

                ticks = time(NULL);

                snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));

                write (connfd, buff, strlen(buff));

                close (connfd);

        }

}

 

 

DateClient.c

 

int main(int argc, char **argv)

{

        int             sockfd, n;

        char            recvline[512];

        struct sockaddr_in servaddr;

        struct hostent *hp, *gethostbyname();

 

        sockfd = socket (AF_INET, SOCK_STREAM, 0);

 

        bzero(&servaddr, sizeof(servaddr));

        servaddr.sin_family = AF_INET;

 

        hp = gethostbyname( “localhost” );

        bcopy ( hp->h_addr, &(servaddr.sin_addr.s_addr), hp->h_length);

        servaddr.sin_port = htons(10117);

 

        if (connect (sockfd, (SA *) & servaddr, sizeof(servaddr)) < 0) {

                perror("connect error");

                exit(-1);

        }

        read (sockfd, recvline, 512);

        printf("%s", recvline);

        exit(0);

}

 

«   To execute:

 

% DateServer

 

    In another window at the same host:

 

% DateClient

 

DateServer.py

#! /usr/bin/env python
import socket
import sys
import os
import datetime

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = ''
port = 10117
s.bind((host, port))
s.listen(1)

while (1):
  conn, addr = s.accept()
  print 'client is at', addr
  #today = datetime.date.today()
  date= datetime.datetime.now().strftime("%A %B %d %H:%M:%S EST %Y \n")
       conn.send(date)
  conn.close()

 

DateClient.py

#! /usr/bin/env python
import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = "localhost"
port = 10117
s.connect((host, port))
date = s.recv(1000000)   
print (date)
s.close()

 

«   To execute:

 

% DateServer.py

    In another window at the same host:

% DateClient.py

 

Mix & Match:

You may use any c/java/python server talk to any c/java/python client.

   Also Try:

% telnet 127.0.0.1 10117

With all 3 servers.

i.e., there are 4x3 = 12 possible combinations.

 

 

 

 


vPipes

·       Ordinary Pipes allow communication in standard producer-consumer style

·       Producer writes to one end (the write-end of the pipe)

·       Consumer reads from the other end (the read-end of the pipe)

·       Ordinary pipes are therefore unidirectional

·       Require parent-child relationship between communicating processes

Description: Description: Description: Description: Description: Picture 2.png

EXAMPLES:

unix_pipe.c

 

#define BUFFER_SIZE 25

#define READ_END        0

#define WRITE_END       1

 

int main(void)

{

        char write_msg[BUFFER_SIZE] = "Greetings";

        char read_msg[BUFFER_SIZE];

        pid_t pid;

        int fd[2];

 

        /** create the pipe */

        pipe(fd)

        /** now fork a child process */

        pid = fork();

       

        if (pid > 0) {  /* parent process */

                /* close the unused end of the pipe */

                close(fd[READ_END]);

                /* write to the pipe */

                write(fd[WRITE_END], write_msg, strlen(write_msg)+1);

                /* close the write end of the pipe */

                close(fd[WRITE_END]);

        }

        else { /* child process */

                /* close the unused end of the pipe */

                close(fd[WRITE_END]);

                /* read from the pipe */

                read(fd[READ_END], read_msg, BUFFER_SIZE);

                printf("child read %s\n",read_msg);

                /* close the write end of the pipe */

                close(fd[READ_END]);

        }

}

 

«   To execute:

 

% unix_pipe

 

pipefork.c:

 

main()
{
   char buf[10];
   int pfd[2];
   pipe(pfd);
   int n;

   if (fork() == 0) {
      write(pfd[1], "child\n", 6);
      n=read(pfd[0], buf, 10);
      write(1, buf, n);
      exit(0);
   }
      n=read(pfd[0], buf, 10);
      write(1, buf, n);
      write(pfd[1], "parent\n", 7);
      wait(NULL);
}

 

«   To execute:

 

% pipefork

 

 

pipe.py:

 

#!/usr/bin/python

import os, sys

# file descriptors r, w for reading and writing
r, w = os.pipe()

processid = os.fork()
if processid: #parent
    os.close(w)
    r = os.fdopen(r)
    str = r.read()
    print "Parent Got: ", str  
    sys.exit(0)
else:
    os.close(r)
    w = os.fdopen(w, 'w')
    w.write("How are you my dear Parent.." )
    w.close()
    sys.exit(0)

 

«   To execute:

 

% pipe.py

 

 

 


vShared Files

 

File Sharing between processes

Description: Description: Description: Description: fileSharing

EXAMPLES:

sharedFile1.c ( single open)

int
main(int argc, char *argv[])
{
  int             n;
  int             i;
  int             sfd;
  pid_t           pid;
  char            buf[1024];

  sfd = open("TempFile", O_RDWR | O_TRUNC | O_CREAT, 0600);

  pid = fork;

  if (pid == 0) {
       sleep(1);
       lseek(sfd, 0, SEEK_SET);
       n = read(sfd, buf, sizeof(buf));
       write(1, buf, n);
       exit(0);
  } else { /* Parent */
       write(sfd, "Hi\n", 3);
       sleep(2);
       exit(0);
  }
}

«   To execute:

 

% sharedFile1

 

sharedFile2.c (two opens)

int
main(int argc, char *argv[])
{
  int             n;
  int             sfd;
  int             sfd2;
  pid_t           pid;
  char            buf[1024];

  pid = fork();

  if (pid == 0) { /* child */
       sleep(1);
       sfd2 = open("TempFile", O_RDWR;

       n = read(sfd2, buf, sizeof(buf));
       write(1, buf, n);
       exit(0);
  } else { /* parent */
       sfd = open("TempFile", O_RDWR | O_TRUNC | O_CREAT, 0600) ;

       write(sfd, "Hi\n", 3);
       sleep(2);
       exit(0);
  }
}

«   To execute:

 

% sharedFile2

 

 

 


v Echo Server (Serving single client)

 

EchoServer.c

 

 

int
main(int argc, char* argv[])
{
    int             len, listenfd, connfd;
    struct sockaddr_in servaddr, cliaddr;
    char            buff[512];
    int             nread;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(atoi(argv[1]));

    bind(listenfd, (SA *) & servaddr, sizeof(servaddr));

    listen(listenfd, 0);

    len = sizeof(cliaddr);
    connfd = accept(listenfd, (SA *) & cliaddr, &len);


   
EchoToClient(connfd);
}

void
EchoToClient(int sockfd)
{

    int             nread;
    char            buffer[512];
    for (;;) {
         nread = read(sockfd, buffer, 512);
         if (nread == 0)
             break;
         write(sockfd, buffer, nread);
    }
}

 

EchoClient.c

 

 

int
main(int argc, char **argv)
{
    int             sockfd;
    struct sockaddr_in servaddr;
    struct hostent *hp, *gethostbyname();
    char            buffer[512];
    int             nread;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    hp = gethostbyname(argv[1]);
    bcopy(hp->h_addr, &(servaddr.sin_addr.s_addr), hp->h_length);
    servaddr.sin_port = htons(atoi(argv[2]));

    if (connect(sockfd, (SA *) & servaddr, sizeof(servaddr)) < 0) {
         perror("connect error");
         exit(-1);
    }
    for (;;) {
         nread = read(0, buffer, 512);
         if (nread == 0)
             exit(0);
         write(sockfd, buffer, nread);


         nread = read(sockfd, buffer, 512);
         write(1, buffer, nread);
    }
}

 

«   To execute:

 

       sirius % EchoServer   10123

 

 In another window for the same host sirius

 

   sirius % EchoClient    localhost     10123

   OR login to another host, e.g., artia

   atria % EchoClient    sirius     10123

 

 


vConcurrency using fork

 

Echo Server (serving multiple clients simultaniusly)

 

EchoServerFork.c

 

 

int
main(int argc, char *argv[])
{
    int             len, listenfd, connfd;
    struct sockaddr_in servaddr, cliaddr;
    char            buff[512];
    int             nread;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(atoi[argv[1]));

    bind(listenfd, (SA *) & servaddr, sizeof(servaddr));

    listen(listenfd, 0);

    for (;;) {
         len = sizeof(cliaddr);
         connfd = accept(listenfd, (SA *) & cliaddr, &len);
         if (fork() == 0)
            
EchoToClient(connfd);
    }
}

void
EchoToClient(int sockfd)
{
    int             nread;
    char            buffer[512];
    for (;;) {
         nread = read(sockfd, buffer, 512);
         if (nread == 0)
             exit(0);
         write(sockfd, buffer, nread);
    }
}

 

EchoClientFork.c 

int
main(int argc, char **argv)
{
    int             sockfd;
    int             pid;
    struct sockaddr_in servaddr;
    struct hostent *hp, *gethostbyname();

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));

    servaddr.sin_family = AF_INET;

    hp = gethostbyname(argv[1]);
    bcopy(hp->h_addr, &(servaddr.sin_addr.s_addr), hp->h_length);
    servaddr.sin_port = htons(atoi(argv[2]));

    if (connect(sockfd, (SA *) & servaddr, sizeof(servaddr)) < 0) {
         perror("connect error");
         exit(-1);
    }

     pid = fork();
    if (pid == 0) { /* child */
         ReadFromKeyBoard(sockfd);
         kill(getppid(), 9);  /* kill parent */
    } else        { /* parent */
         ReadFromSocket(sockfd);
         kill(pid, 9); /* kill child */
    }
}

void
ReadFromKeyBoard(int sockfd)
{
    int             nread;
    char            buffer[512];
    for (;;) {
         nread = read(0, buffer, 512);
         if (nread == 0)
             break;
         write(sockfd, buffer, nread);
    }
}

void
ReadFromSocket(int sockfd)
{
    int             nread;
    char            buffer[512];
    for (;;) {
         nread = read(sockfd, buffer, 512);
         if (nread == 0)
             break;
         write(1, buffer, nread);
    }
}

 

«   To execute:

 

cirius % EchoServerFork   10123

 

    In another window for the same host (vega)

 

% EchoClientFork    localhost     10123

 

    In another window for the another host (antares)

 

atria % EchoClientFork    cirius     10123

 

Repeat for any number of other windows.

 

 

 


v Be Clever!

 

Echo Client Simple Version: EchoClientForkShort.c

           ..............

      pid = fork();

      if (pid == 0) {

           ReadFrom(0, sockfd);

           kill(getppid(), 9);

      } else {

           ReadFrom(sockfd, 1);

           kill(pid, 9);

      }

     ........

 

void ReadFrom(int fd1, int fd2)

{

 

      int             nread;

      char            buffer[512];

      for (;;) {

           nread = read(fd1, buffer, 512);

           if (nread == 0)

                 break;

           write(fd2, buffer, nread);

      }

 

 }

 

 


v Be Smart!

 

Echo Client Optimal Version (remember  Kernighan’s Law  for Debugging! ):

         Note that writing to 0 is the same as writing to 1!

 

EchoClientForkOptimum.c

        
     ........
     ........
 
      dup2(sockfd, 1);
      close(sockfd);
      pid = fork();
      if (pid == 0) {
           ReadFrom(0);
           kill(getppid(), 9);
      } else {
           ReadFrom(1);
           kill(pid, 9);
      }
}
 
 
void ReadFrom(int fd)
{
 
      int             nread;
      char            buffer[512];
      for (;;) {
           nread = read(fd, buffer, 512);
           if (nread == 0)
                 break;
           write((fd + 1) % 2, buffer, nread);
      }
}
 
 

 


v Python Echo Server & Client 

 

EchoServerFork.py

#! /usr/bin/env python
import socket
import sys
import os
import datetime

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = ''
port = int(sys.argv[1])
s.bind((host, port))
s.listen(1)

while (1):
conn, addr = s.accept()
print 'client is at', addr
childpid = os.fork()
if childpid == 0:
              print("child, serving echo client")
       while (1):
                    data = conn.recv(1000000)
              if not data:           # if end of data, leave loop
                    print("child, echo client is done")
                    conn.close()
                    exit(0)

                    conn.send(data)
else:
              print("I am the parent of: ", childpid)
       conn.close()

 

EchoClient.py

#! /usr/bin/env python
import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = sys.argv[1] # server address
port = int(sys.argv[2]) # server port
s.connect((host, port))

while(1):
    print 'type a line (type CTRL-D when done)'
    line = sys.stdin.readline()    # keyboard input, ctrl-d to end
    if not line:                   # if end of data, leave loop
       break
    s.send(line)
    data = s.recv(1000000)         # read up to 1000000 bytes
    print 'received', len(data), 'bytes: ', data

s.close()

 

«      To execute:

 

       sirius % EchoServerFork.py   10123

 

 In another window for the same host

 

   % EchoClient.py    localhost     10123

   OR

   atria % EchoClient.py    sirius     10123

 

 


Signals

Basic Signal Handling:

 

kill (pid, sig)

 

Send process pid signal sig
(To list all available signals type: % kill -l )

It is called kill since the default action is to kill the process.

 

signal (sig, handler)

To catch & handle signal.

When signal sig occurs, call function handler

 

pause ()

To wait for the arrival of any signal

 

 

Example: signal1.c

 

main ()

{

signal(SIGUSR1, handler);
signal(SIGUSR2, handler);

for (;;) pause();

}

handler(int sig)
{

/* Print received signal */
psignal(sig, "Received signal");

}

 

To execute:

 

% signal1

 

% kill -USR1 12345 //use ps to find pid of signal1 e.g., 12345


Recived signal: User Signal 1

 

To list signals use:

 

% kill -l

HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM

STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL

PWR SYS RTMIN RTMIN+1 RTMIN+2 RTMIN+3 RTMAX-3 RTMAX-2 RTMAX-1 RTMAX

 

Then you can use:


% kill -10 12345 //signal #10 is USR1


Recived signal: User Signal 2

% kill -KILL 12345 //signal #9 is KILL
Killed

 

A process can NOT catch or ignore (using SIG_IGN) the KILL signal.

 

Example: basic-signal.c


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

int i;
signal(SIGINT,
SIGhandler);

printf("\nParent Process, PID: %d\n", getpid());

for(;;){

printf("HI %c\n", (i++) %26 +'A');
sleep(1);

}

}

void
SIGhandler(int sig)
{

signal(sig, SIGhandler);
psignal(sig, "\nReceived SIGhandler1 signal");

}

 

To execute:

 

% basic-signal

 

Type: CTRL-C

OR

Type: CTRL-\ to exit

 

 

Example: fork-signal.c

 

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

signal(SIGINT, SIGhandler);

if (fork() == 0){
     printf("Child Process1, PID: %d", getpid());
     for (;;) pause();
}


if (fork() == 0){
   signal(SIGINT, SIG_IGN);
     printf("Child Process2, PID: %d", getpid());
     for (;;) pause();
}

printf("Parent Process, PID: %d", getpid());

for (;;) pause();


}

void SIGhandler(int sig)
{

printf("Process, PID: %d", getpid());
signal(sig, SIGhandler);
psignal(sig, "Received SIGhandler signal");

}

 

 

To execute:

 

% fork-signal

 

Type: CTRL-C

OR

Type: CTRL-\ to exit

 

 

Python Signal  Example:  signal.py

#! /usr/bin/python
import os
import signal
import time
import sys

def INThandle (signum, frame ):

    print ("Got SIGINT, PID: ", os.getpid())
    print( "SIGINT number:", signum)
    pass

 

signal.signal( signal.SIGINT, INThandle )
childpid = os.fork()
if childpid == 0:

    print("I am child, my PID: ", os.getpid())
    signal.pause()
    print("Child: got SIGINT signal")

else:

    print("I am the parent, my PID: ", os.getpid())
    print("My child PID: ", childpid)
    signal.pause()
    print("Parent: got SIGINT signal")

 

To execute:

 

%  signal.py

 

 Type: CTRL-C

      OR 

 Type: CTRL-\ to exit