02 Unix System Programming

  • Upload
    -

  • View
    235

  • Download
    0

Embed Size (px)

Citation preview

  • 7/31/2019 02 Unix System Programming

    1/44

    Introduction to UNIX

    System ProgrammingBy

    Armin R. Mikler

  • 7/31/2019 02 Unix System Programming

    2/44

    Overview

    Basic UNIX Commands Files Buffered vs. non-buffered I/O Basic System Calls

    Processes Whats a process anyway? The fork() System Call Coordinating Processes (wait, exit, etc)

    Inter-Process Communication Pipes

  • 7/31/2019 02 Unix System Programming

    3/44

    Basic UNIX Commands Login

    username password

    ==> User Shell.

    The User Shell is: The Command Interpreter A running program UNIX Commands are

    (often small) programs. What else does the Shell

    do?

    Basic Commands: who am I pwd who what

    ps (*) finger ls mkdir

    rm (-i -f -r) touch cat (note: there is no dog) grep

  • 7/31/2019 02 Unix System Programming

    4/44

    more basic UNIX Editors

    emacs vi joe sed

    and others Compilers/Interpreters

    gcc g++

    perl java etc.

    The UNIX Manual use the manual pages to

    get information about aspecific command orsystem call.

    The UNIX manual isdivided into sections.

    Careful!! The same systemcall can (and does) appear

    in different sections withdifferent context. Use man -si subject to

    refer to section i.

  • 7/31/2019 02 Unix System Programming

    5/44

    man pages

    man -k keyword(s) prints the header line of manual pages that contain thekeyword(s)

    apropos keyword(s)

    same as man -k Questions:

    Which manual section contains UNIX user commands? Which manual section contains UNIX system calls?

    What is the difference between commands and systemcalls?

    TRY xman, the manual pages for X11.

  • 7/31/2019 02 Unix System Programming

    6/44

    Files

    UNIX Input/Output operations are based on theconcept of files. Files are an abstraction of specific I/O devices. A very small set of system calls provide the

    primitives that give direct access to I/O facilitiesof the UNIX kernel. Most I/O operations rely on the use of these

    primitives. We must remember that the basic I/O primitives

    are system calls, executed by the kernel. Whatdoes that mean to us as programmers???

  • 7/31/2019 02 Unix System Programming

    7/44

    UNIX I/O Primitives

    open: Opens a file for reading or writing, orcreates an empty file. create: Creates an empty file close: Closes a previously opened file

    read: Extracts information from a file write: Places information into a file lseek: Moves to a specific byte in the file

    unlink: Removes a file remove: Removes a file

  • 7/31/2019 02 Unix System Programming

    8/44

    A rudimentary example:#include /* controls file attributes */

    #include /* defines symbolic constants */main()

    {

    int fd; /* a file descriptor */

    ssize_t nread;/* number of bytes read */

    char buf[1024]; /* data buffer *//* open the file data for reading */

    fd = open(data, O_RDONLY);

    /* read in the data */

    nread = read(fd, buf, 1024);

    /* close the file */close(fd);

    }

  • 7/31/2019 02 Unix System Programming

    9/44

    Buffered vs unbuffered I/O The system can execute in user mode or kernel

    mode! Memory is divided into user space and kernel

    space!

    What happens when we write to a file? the write call forces a context switch to the system. What?? the system copies the specified number of bytes from user space

    into kernel space. (into mbufs) the system wakes up the device driver to write these mbufs to

    the physical device (if the file-system is in synchronous mode). the system selects a new process to run. finally, control is returned to the process that executed the

    write call.

    Discuss the effects on the performance of your

    program!

  • 7/31/2019 02 Unix System Programming

    10/44

    Un-buffered I/O Every read and write is executed by the kernel. Hence, every read and write will cause a context

    switch in order for the system routines toexecute.

    Why do we suffer performance loss? How can we reduce the loss of performance?

    ==> We could try to move as much data as possiblewith each system call.

    How can we measure the performance?

  • 7/31/2019 02 Unix System Programming

    11/44

    Buffered I/O explicit versus implicit buffering:

    explicit - collect as many bytes as you can beforewriting to file and read more than a single byte at atime.

    However, use the basic UNIX I/O primitives Careful !! Your program my behave differently on different

    systems. Here, the programmer is explicitly controlling the buffer-size

    implicit - use the Stream facility provided by FILE *fd, fopen, fprintf, fflush, fclose, ... etc. a FILE structure contains a buffer (in user space) that

    is usually the size of the disk blocking factor (512 or1024)

  • 7/31/2019 02 Unix System Programming

    12/44

    File Locking Consider the following problem:

    Processes can obtain a unique integer by readingfrom a file. The file contains a single integer (atall times), which must be incremented by the

    process that executes a read. Since multipleprocesses can compete for the file (a uniqueinteger), we must make sure that the file accessis synchronized.

    HOW??

    What happens if we use buffered I/O ?

  • 7/31/2019 02 Unix System Programming

    13/44

    lockf() lockf() is a C-Library function for locking records

    of a file. Its prototype isint lockf( int fd, int func, long size);

    func-parameters are: F_ULOCK: 0 (unlock a locked section) F_LOCK: 1 (locks a section) F_TLOCK: 2(Test and Lock a section)

    F_TEST: 3 (Test section for Locks) see the UNIX manual pages!!

  • 7/31/2019 02 Unix System Programming

    14/44

    If we rewind the file before locking AND use asize of 0L as the corresponding size parameter,the entire file is being locked.

    lseek(fd, 0L, 0) can be used to rewind the file (fd)

    to the beginning.

  • 7/31/2019 02 Unix System Programming

    15/44

    flock() flock() is a UNIX system call to apply or remove

    an advisory lock to an open file The locking is only on an advisory basis (not

    absolute)

    Prototype: int flock(fd, operation) see manual pages

  • 7/31/2019 02 Unix System Programming

    16/44

    UNIX Processes A program that has started is manifested in the

    context of a process. A process in the system is represented:

    Process Identification Elements

    Process State Information Process Control Information User Stack Private User Address Space, Programs and Data

    Shared Address Space

  • 7/31/2019 02 Unix System Programming

    17/44

    Process Control Block Process Information, Process State Information,

    and Process Control Information constitute thePCB.

    All Process State Information is stored in the

    Process Status Word (PSW).

    All information needed by the OS to manage theprocess is contained in the PCB.

    A UNIX process can be in a variety of states:

  • 7/31/2019 02 Unix System Programming

    18/44

    States of a UNIX Process User running: Process executes in user mode

    Kernel running: Process executes in kernel mode Ready to run in memory: process is waiting to be scheduled Asleep in memory: waiting for an event Ready to run swapped: ready to run but requires swapping in Preempted: Process is returning from kernel to user-mode but

    the system has scheduled another process instead Created: Process is newly created and not ready to run Zombie: Process no longer exists, but it leaves a record for its

    parent process to collect.

    See Process State Diagram!!

  • 7/31/2019 02 Unix System Programming

    19/44

    Creating a new process In UNIX, a new process is created by means of

    the fork() - system call. The OS performs thefollowing functions:

    It allocates a slot in the process table for the new process It assigns a unique ID to the new process

    It makes a copy of process image of the parent (except sharedmemory)

    It assigns the child process to the Ready to Run State It returns the ID of the child to the parent process, and 0 to

    the child.

    Note, the fork() call actually is called once but returnstwice - namely in the parent and the child process.

  • 7/31/2019 02 Unix System Programming

    20/44

    Fork() Pid_t fork(void) is the prototype of the fork() call. Remember that fork() returns twice

    in the newly created (child) process with return value 0 in the calling process (parent) with return value = pid of

    the new process. A negative return value (-1) indicates that the call has

    failed

    Different return values are the key for

    distinguishing parent process from child process! The child process is an exact copy of the parent,yet, it is a copy i.e. an identical but separate processimage.

  • 7/31/2019 02 Unix System Programming

    21/44

    A fork() Example#include

    main(){

    pid_t pid /* process id */

    printf(just one process before the fork()\n);

    pid = fork();if(pid == 0)

    printf(I am the child process\n);

    else if(pid > 0)

    printf(I am the parent process\n);

    else

    printf(DANGER Mr. Robinson - the fork() has failed\n)

    }

  • 7/31/2019 02 Unix System Programming

    22/44

    Basic Process Coordination The exit() call is used to terminate a process.

    Its prototype is: void exit(int status), where status isused as the return value of the process.

    exit(i) can be used to announce success and failure tothe calling process.

    The wait() call is used to temporarily suspend theparent process until one of the child processesterminates. The prototype is: pid_t wait(int *status), where status

    is a pointer to an integer to which the childs statusinformation is being assigned.

    wait() will return with a pid when any one of the childrenterminates or with -1 when no children exist.

  • 7/31/2019 02 Unix System Programming

    23/44

    more coordination To wait for a particular child process to

    terminate, we can use the waitpid() call. Prototype: pid_t waitpid(pid_t pid, int *status, int opt)

    Sometimes we want to get information about the

    process or its parent. getpid() returns the process id getppid() returns the parents process id getuid() returns the users id

    use the manual pages for more id information.

  • 7/31/2019 02 Unix System Programming

    24/44

    Orphans and Zombies or MIAs A child process whose parent has terminated is

    referred to as orphan. When a child exits when its parent is not currently

    executing a wait(), a zombie emerges.

    A zombie is not really a process as it has terminated butthe system retains an entry in the process table for thenon-existing child process.

    A zombie is put to rest when the parent finally executesa wait().

    When a parent terminates, orphans and zombiesare adopted by the init process (prosess-id -1) ofthe system.

  • 7/31/2019 02 Unix System Programming

    25/44

    Inter-Process Communication In addition to synchronizing different processes,

    we may want to be able to communicate databetween them.

    Note, that we are dealing with processes in the

    same machine. Hence, we can use shared memorysegments to send messages between processes. One of the way to establish a communication

    channel between processes with a parent-child

    relationship is through the concept of pipes. We can use the pipe() system call to create a pipe.

  • 7/31/2019 02 Unix System Programming

    26/44

    UNIX Pipes At the UNIX command level, we can use pipes to

    channel the output of one command into another ls | wc

    At the process level we use the pipe() system call.

    prototype: int pipe(int filedes[2]) filedes[0] will be a file descriptor open for reading filedes[1] will be a file descriptor open for writing the return value of pipe() is -1 if it could not

    successfully open the file descriptors.

    But how does this help to communicate betweenprocesses?

  • 7/31/2019 02 Unix System Programming

    27/44

    Basic Inter-ProcessCommunication

    by

    Armin R. Mikler

  • 7/31/2019 02 Unix System Programming

    28/44

    Overview What is IPC ? How can we achieve IPC?

    The pipeat the shell level! The pipebetween

    processes!

    The pipe()system call! closing the pipe! Programming with pipes.

    size of a pipe Non-blocking read() and

    write() The select() system call

    FIFOs - named Pipes FIFOs vs. regular pipes Steps for using a FIFO

    mkfifo to make a FIFO open the FIFO

    Other IPC concepts signals shared memory semaphores sockets

  • 7/31/2019 02 Unix System Programming

    29/44

    What is IPC Inter-Process Communication allows different

    processes to exchange information and synchronizetheir actions.

    Why do processes have to synchronize their actions?

    We need to distinguish how processes may be related: Parent / Child relationship i.e., the child process was created

    by the parent Processes that are notrelated yet execute on the same host

    Processes that are not related and execute on differenthosts

    Why do we have to make this distinctions?

  • 7/31/2019 02 Unix System Programming

    30/44

    some similarities consider a program that consists of multiple

    functions. how can we exchange information between the main()

    function and any of the other functions func()? how do we produce side effects in func()that are visible

    in main()? what do we need to do to guarantee that func()accesses

    the same variables as main()?

    The trick is to either allow different functions towork with identical memory locations or to createa communication channelin the form of parameterlists or return values.

  • 7/31/2019 02 Unix System Programming

    31/44

  • 7/31/2019 02 Unix System Programming

    32/44

    IPC between processeson different systems

    User Process

    OS-Kernel

    User Process

    OS-Kernel

    Network

  • 7/31/2019 02 Unix System Programming

    33/44

    How do we achieve IPC Processes need to use some facility that they have

    in common. Both processes must speak the same IPC-

    language.

    What facilities can two or more processes sharewhen they reside on the same host? Memory

    File System Space Communication Facilities Common communication protocol provided by the OS

    (signals)

  • 7/31/2019 02 Unix System Programming

    34/44

    Inter-Process Communicationusing PIPES In addition to synchronizing different processes, we

    may want to be able to communicate data betweenthem.

    For the time, we are dealing with processes in thesame machine. Hence, we can use shared memorysegments to send messages between processes.

    A pipe is a one-way communication channel which canbe used to connect two relatedprocesses

  • 7/31/2019 02 Unix System Programming

    35/44

    Pipes contd

    Unix provides a construct called pipe, acommunication channel through which twoprocesses can exchange information.

    One of the way to establish a communicationchannel between processes with a parent-childrelationship is through the concept of pipes.

    Why do the processes need to be related?

  • 7/31/2019 02 Unix System Programming

    36/44

    UNIX Pipes contd At the UNIX command level, we can use pipes to

    channel the output of one command into another ls | wc the shell actually creates a child process, uses exec()to

    execute the corresponding program (i.e., lsand wc)

    How does the shell implement the pipe-command

    i.e., ls|wc ??

    How would you implement the ability to pipe??Discuss....

  • 7/31/2019 02 Unix System Programming

    37/44

    the pipe()system call At the process level we use the pipe()system call.

    prototype: int pipe(int filedes[2]) filedes[0] will be a file descriptor open for reading filedes[1] will be a file descriptor open for writing the return value of pipe() is -1 if it could not

    successfully open the file descriptors. But how does this help to communicate between

    processes??

  • 7/31/2019 02 Unix System Programming

    38/44

    example#include ....

    main(){

    int p[2], pid;char buf[64];

    if(pipe(p) == -1)

    {perror(pipe call);

    exit(1);}

    /* at this point we have apipe p with p[0] opened forreading and p[1] openedfor writing - just like afile */

    write(p[1], hi

    there, 9);

    read(p[0], buf, 9);

    printf(%s\n, buf);

    }

  • 7/31/2019 02 Unix System Programming

    39/44

    A pipe to itself ?

    Process

    write()

    read()

  • 7/31/2019 02 Unix System Programming

    40/44

    A channel between two processes Remember: parent/child relationship! What does that mean?

    the child was created by a fork()call that was executed by theparent.

    the child process is an image of the parent process ---> all the file

    descriptors that are opened by the parent are now available in thechild.

    The file descriptors refer to the same I/O entity, in this case apipe.

    The pipe is inherited by the child and may be passed on to the

    grand-children by the child process or other children by theparent.

    This can easily lead to a chaotic conglomeration of pipesthroughout our system of processes

  • 7/31/2019 02 Unix System Programming

    41/44

    The open pipe problem

    Child Process

    write()

    read()

    Parent Process

    write()

    read()

  • 7/31/2019 02 Unix System Programming

    42/44

    The fix

    Child Process

    write()

    read()

    write()

    read()

  • 7/31/2019 02 Unix System Programming

    43/44

    closing the pipe The file descriptors associated with a pipe can be

    closed with the close(fd)system call Some Rules:

    A read() on a pipe will generally block until either dataappears or all processes have closed the write filedescriptor of the pipe!

    Closing the write fd while other processes are writing tothe pipe does not have any effect!

    Closing the read fd while others are still reading will not

    have any effect! Closing the read while others are still writing will cause

    an error to be returned by the write and a signal is sentby the kernel (Broken Pipe!!)

  • 7/31/2019 02 Unix System Programming

    44/44

    The size of a pipe In most cases, we only transfer small amounts of

    data through a pipe - but we for some applicationswe may want to send and receive large data blocks.

    A valid question is: How much data will fit into apipe ??

    Why do we care? Remember - a write()will blockuntil the requested number of bytes have beenwritten.

    The POSIX standard specifies a minimum size of512 bytes!