system v ipc provides three mechanisms for interprocess communication (ipc) : messages : exchange...

Post on 02-Jan-2016

234 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

System V IPC

Provides three mechanisms for InterProcess Communication (IPC) :

Messages : exchange messages with any process or server.

Semaphores : allow unrelated processes to synchronize execution.

Shared memory : allow unrelated processes to share memory.

Semaphores - General

Used to monitor and control the availability of system resources such as shared memory segments.

Can be operated on as individual units or as elements in a set.

A semaphore set consists of a control structure and an array of individual semaphores (default 25 elements).

Semaphores - Functions

The semget() function initializes or gains access to a semaphore.

semid = semget (key_t key, int nsems, int semflg); key : value associated with the semaphore ID nsems : number of semaphores in array semflg :

IPC_CREAT used to create a new resource IPC_EXCL used with IPC_CREAT to ensure failure if the

resource exists. rwxrwxrwx access permissions.

returns : semid on success. -1 on failure.

Semaphores - Functions

The semctl() function allows a process to alter permissions and other characteristics of a semaphore set.

int semctl (int semid, int semnum, int cmd, union semun arg); semid : id obtained by a call to semget(). cmd : control flags

GETVAL SETVAL etc…

returns : 0 on success. -1 on failure. arg is a union : (usually optional) union semun{

int val; struct semid_ds *buf; ushort *array;

}

Semaphores - Functions

The semop() function performs operations on a semaphore set.int semop (int semid, struct sembuf *sops, unsigned nsops);

semid : id obtained by a call to semget().

sops : array of semaphore operations. nsops : number of operations in array.

Operations are described by a structure sembuf: struct sembuf{ ushort sem_num; /* semaphore index in array */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */. }

Shared Memory - General

An efficient means of passing data between processes.

One process will create a memory portion which other processes (if permitted) can access.

When write access is allowed for more than one process, an outside protocol or mechanism such as a semaphore can be used to prevent inconsistencies and collisions.

Shared Memory - Functions

The shmget() function is used to obtain access to a shared memory segment.

shmid=shmget(key_t key, int size, int shmflg); key : key value of shared memory size : size of the segment in bytes shmflg :

IPC_CREAT used to create a new resource IPC_EXCL used with IPC_CREAT to ensure failure if the resource

exists. rwxrwxrwx access permissions.

returns : shmid on success. -1 on failure.

Shared Memory - Functions

The shmctl() is used to alter the permissions and other characteristics of a shared memory segment.

int shmctl (int shmid, int cmd, struct shmid_ds *buf); shmid : id got from call to shmget(). cmd :control commands

IPC_RMID IPC_SET IPC_STAT etc…

buf : used to read (IPC_STAT) or write (IPC_SET) information. returns : 0 on success, -1 on failure.

Shared Memory - Functions

shmat() and shmdt() functions are used to attach and detach shared memory segments respectively.

void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr);

shmat() returns a pointer to the head of the shared segment associated with a valid shmid.( values of shmaddr and shmflg are usually set to 0)

shmdt() detaches the shared memory segment located at the address indicated by shmaddr. returns : 0 on success. -1 on failure

Shared Memory – Example(1/7)

shm_server.c creates the string and shared memory portion.

shm_client.c attaches itself to the created shared memory

portion and uses the string

Shared Memory – Example(2/7)shm_server.c

#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdio.h>

#define SHMSZ 27

main(){ char c; int shmid; key_t key; char *shm, *s; /* * We'll name our shared memory segment * "5678".

*/key = 5678;

Shared Memory – Example(3/7)

/* * Create the segment.*/ if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { perror("shmget"); exit(1); } /* * Now we attach the segment to our data space. */ if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

perror("shmat"); exit(1); } /* * Now put some things into the memory for the * other process to read. */ s = shm;

Shared Memory – Example(4/7)

for (c = 'a'; c <= 'z'; c++) *s++ = c;

*s = NULL; /* * Finally, we wait until the other process * changes the first character of our memory * to '*', indicating that it has read what * we put there. */ while (*shm != '*')

sleep(1); exit(0);

} /*main*/

Shared Memory – Example(5/7)shm_client.c

#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdio.h>

#define SHMSZ 27

main(){ int shmid; key_t key; char *shm, *s; /* * We need to get the segment named * "5678", created by the server. */ key = 5678;

Shared Memory – Example(6/7)

/*

* Locate the segment.

*/

if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {

perror("shmget"); exit(1); }

/*

* Now we attach the segment to our data space.

*/

if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

perror("shmat"); exit(1); }

Shared Memory – Example(7/7)

/* * Now read what the server put in the memory. */ for (s = shm; *s != NULL; s++)

putchar(*s); putchar('\n'); /* * Finally, change the first character of the * segment to '*', indicating we have read * the segment. */ *shm = '*'; exit(0);

} /*main*/

System calls

Are functions that used to control user processes

fork() exit()

wait()

A process calling fork() spawns a child process.

The child is almost an identical clone of the parent:Program TextStackData

The fork() System Call (1)

#include <sys/types.h>#include <unistd.h>

pid_t fork(void);

The fork() System Call (2)

The fork() is one of the those system calls, which is called once, but returns twice!

After fork() both the parent and the child are executing the same program.

On error, fork() returns -1PID=28

p1

PID=28

p1

PID=34

c1

fork()

Consider a piece of program(see fork_pid.c example):...pid_t pid = fork();printf(“PID: %d\n”, pid);...

The parent will print:PID: 34

And the child will always print:PID: 0

The fork() System Call (3)

Remember, after fork() the execution order is not guaranteed.

Simple fork() examples: fork_pid.c prints out return from fork() fork_child.c fork_child.c distinguishes

between the parent and the child

#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>

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

pid_t pid = fork(); /*pid is actually an integer*/printf("PID: %d\n", pid); /*Child will print 0, parent an ID specified by

the OS*/exit(0); /*Βoth terminate right after, not very exciting,

I know.*/}

fork_pid.c

#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>

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

pid_t pid = fork(); /* fork a child */printf("PID: %d\n", pid); /* both execute this line */

if(pid == 0) /* child plays here */{

printf("Hello I'm a child!! My PID=%d\n", getpid());}else /* parent goes here */{

printf("Hi! I'm a parent (my PID=%d) of the child with PID=%d\n", getpid(), pid);}

/* both terminate */printf("Process with PID=%d terminates...\n", getpid());exit(0);

}

fork_child.c

The exit() System Call

This call gracefully terminates process execution. Gracefully means it does clean up and release of resources, and puts the process into the zombie state.

By calling wait(), the parent cleans up all its zombie children. exit() specifies a return value from the program, which a

parent process might want to examine as well as status of the dead process.

_exit() call is another possibility of quick death without cleanup.

#include <stdlib.h>

void exit(int status);

The wait() System Call

Forces the parent to suspend execution, i.e. wait for its children or a specific child to die (terminate is more appropriate terminology, but a bit less common).

The wait() System Call (2)

The wait() causes the parent to wait for any child process.

The waitpid() waits for the child with specific PID. The status, if not NULL, stores exit information of the

child The return value is:

PID of the exited process, if no error (-1) if an error has happened

#include <sys/types.h>#include <sys/wait.h>

pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);

References

man 2 fork man 2 wait man 3 exit

top related