2. Standardization and Implementation 3. File I/O

31  Download (0)

全文

(1)

系統程式

郭大維教授/施吉昇教授 臺灣大學資訊工程系

(2)

Contents

1. Preface/Introduction

2. Standardization and Implementation 3. File I/O

4. Standard I/O Library 5. Files and Directories

6. System Data Files and Information 7. Environment of a Unix Process

8. Process Control 9. Signals

10. Inter-process Communication

(3)

Interprocess

Communication

ƒ Except for communicating via the file system, processes can communicate via various IPCs.

● streams

● sockets

● shared memory

● semaphores

● message queues

● named stream pipes

● Stream pipes ●

(full duplex)

● FIFOs

● pipes (half duplex)

4.3+BSD 4.3BSD

SVR4 SVR3.2

SVR2 V7

XPG3 POSIX.1

IPC type

(4)

Pipes

ƒ Pipes have two limitations:

ƒ They are half-duplex.

ƒ They can be used between processes that have a common ancestor.

ƒ Stream pipes are duplex and named stream pipes can be used between process not having the same ancestor.

ƒ pipe function

#include <unistd.h>

int pipe( int filedes[2] );

(5)

Unix pipes

user process

fd[0] fd[1]

user process

fd[0] fd[1]

pipe

kernel

(6)

Pipes between processes

parent process

fd[0] fd[1]

pipe kernel

child process

fd[0] fd[1]

fork

(7)

Useful pipe

parent process

fd[0] fd[1]

pipe kernel

child process

fd[0] fd[1]

fork

Pipe from parent process to child process

(8)

Read from/Write to pipes

ƒ When the write end is closed, reading from a pipe returns 0

ƒ When the read end of a pipe is closed, writing to a pipe triggers SIGPIPE signal.

ƒ Pipe buffer size:

ƒ Constant PIPE_BUF specifies the pipe buffer size.

ƒ Writing PIPE_BUF or less will not be interleaved.

ƒ Program 14.1: creating a pipe from the parent to

the child and send data down the pipe.

(9)

Connecting pipes to standard input/output

parent process

fd[0] fd[1]

pipe kernel

child process

fd[0] fd[1]

fork

Pipe from parent process to child process

STDIN_FILENO

(10)

Using pipes for parent-child synchronization

pfd1[1]

pfd2[0]

pfd1[0]

pfd2[1]

“P”

“C”

parent process child process

TELL_CHILD()

TELL_PARENT()

(11)

popen and pclose function

ƒ Two functions handling all the dirty works:

ƒ the creation of a pipe,

ƒ the fork of a child,

ƒ closing the unused ends of the pipe,

ƒ exec uting a shell to execute the command, and

ƒ wait ing for the command to terminate.

ƒ Functions:

# include <stdio.h>

FILE *popen(const char *cmdstring, const char *type);

int pclose(FILE *fp);

ƒ Rewrite 14.2 using popen and pclose

(12)

fp = popen( command, “r”)

parent process cmdstring(child)

stdout fp

fp = popen( command, “w”)

parent process cmdstring(child)

stdin

fp

(13)

Implementing popen and pclose

ƒ We have to keep the PIDs of child processes to synchronize.

ƒ popen and pclose could be called several times in a process.

ƒ How to keep the PIDs?

ƒ We have to close the files opened by the

child processes whose PIDs may not be

available.

(14)

Another example

ƒ An application to write a prompt to standard output and read a line from standard input.

user at a terminal prompt

parent process

stdout

userinput

USERINPUT

(15)

Another example

ƒ An application to write a prompt to standard output and read a line from standard input.

user at a terminal

user input prompt

popen pipe

parent process filter program

stdout

stdin

stdout

(16)

Coprocesses

ƒ Coprocesses: a process runs in the

background from a shell and its standard input and output are connected to another program.

ƒ Who are providing coprocesses?

ƒ KornShell provides coprocess

ƒ Bourne shell and C shell do not.

stdout stdin fd1[1]

fd0[0]

parent process child process (coprocess)

(17)

An example of Co-Process

ƒ Program 14.8 is a simple co-process that reads two numbers from its stdin and writes the sum to its stdout.

ƒ Program 14.9 invokes the co-process, after reading two numbers from its stdin.

ƒ Program 14.10 re-writes the co-process using standard I/O.

ƒ But, the two programs could cause a deadlock.

(18)

Dining Philosophers

ƒ Dining Philosophers problem is invented by E. W. Dijkstra in 1965.

ƒ Philosophers only think and eat, and may

starve.

(19)

Deadlock in Program 14.10

ƒ The parent process and co-process are blocked by read.

write()

fgets() parent process child process (coprocess)

read()

setbuf(,,_IOBUF, 0)

(20)

FIFOs

ƒ FIFOs – named pipes for (un-)related processes to exchange data.

ƒ A file type – st_mode (S_ISFIFO macro)

ƒ Data in a FIFO removed when the last referencing process terminates.

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

ƒ mode and usr/grp ownership = those of a file

ƒ Op’s: open, close, read, write, unlink, etc.

(21)

FIFOs

ƒ O_NONBLOCK

ƒ NO Æ an open for read-only blocks until some other process opens the FIFO for writing (write-only as well).

ƒ Yes Æ an open for read-only always returns, while that for write-only returns with an error (errno=ENXIO) if there is no reader.

ƒ Write for a no-reader FIFO Æ SIGPIPE

ƒ Closing of the last writer Æ EOF

ƒ Atomic writes

ƒ PIPE_BUF

(22)

FIFOs

ƒ Example – Stream Duplication

mkfifo fifo1

prog3 < fifo1 &

prog1 < infile | tee fifo1 | prog2

infile prog1 tee

prog2

prog3

FIFO

(23)

FIFOs

ƒ Example – Client-Server Communication

ƒ One server & multiple clients

ƒ Issues: replies, SIGPIPE, removing of all clients

client

server

client

well-known FIFO client-specific

FIFO

client-specific

FIFO

(24)

System V IPC

ƒ System V IPC

ƒ Message queue, semaphore, shared memory segment

ƒ An ipc_perm structure for each IPC structure

ƒ An IPC identifier – slot usage sequence number [0…max#]

(MSGMNI)

ƒ Key – msgget, semget, shmget

ƒ The Kernel converts it into an identifier.

ƒ IPC_PRIVATE

ƒ Key stored in a header.

struct ipc_perm {

uid_t uid; /* owner euid */

gid_t gid; /* owner egid */

uid_t cuid; /* creator euid */

gid_t cgid; /* creator egid */

mode_t mode; /* access */

ulong seg; /* slot usage seq # */

key_t key;

(25)

System V IPC

ƒ Creation of a new IPC structure

ƒ Key = IPC_PRIVATE

ƒ Key is not associated with any other ICP structure & IPC_CREAT bit is on in flag.

ƒ IPC_CREAT + IPC_EXCL

ƒ errno = EEXIST

ƒ Referencing of a IPC structure

ƒ Key!= IPC_PRIVATE Æ Use the key used in the creation of the structure &

IPC_CREAT bit is not set.

ƒ Key== IPC_PRIVATE Æ Use the identifier.

(26)

System V IPC

ƒ Figure 14.14 – access rights

ƒ Modifications to an ipc_perm structure

ƒ uid, gid, mode – msgctl, semctl, shmctl

ƒ Problems

ƒ No reference count!

ƒ No name in the file system.

ƒ Needs of brand new functions

ƒ No multiplexing I/O

ƒ Advantages – Figure 14.15 (Page 452)

ƒ Reliable, flow control, records, msg types or

struct ipc_perm {

uid_t uid; /* owner euid */

gid_t gid; /* owner egid */

uid_t cuid; /* creator euid */

gid_t cgid; /* creator egid */

mode_t mode; /* access */

ulong seg; /* slot usage seq # */

key_t key; }

(27)

Message Queues

ƒ Message Queue or Queue

ƒ A linked list of messages stored within the kernel and with a queue ID

struct msqid_ds {

struct ipc_perm msg_perm;

struct msg *msg_first; /* ptr to the first msg */

struct msg *msg_last; /* ptr to the last msg */

ulong msg_cbytes; /* current # of bytes */

ulong msg_qnum; /* # of msgs */

ulong msg_qbytes; /* max # of bytes */

pid_t msg_lspid; /* pid of the last msgsnd() */

pid_t msg_lrpid; /* pid of the last msgrcv() */

time_t msg_stime; /* the last msgsnd() time */

time_t msg_rtime; /* the last msgrcv() time */

time_t msg_ctime; /* last change time */

}

• Figure 14.16 – Page 454

• msg_first and msg_last are useless!

• Msgs could be fetched

bsed on their type field.

(28)

Message Queues

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgget(key_t key, int flag);

ƒ Key Æ identifier, flag Æ mode (Figure 14.14)

ƒ msg_qnum=msg_lspid=msg_lrpid=msg_stim e=msg_rtime=0

ƒ msg_ctime=the current time

ƒ msg_qbytes=MSGMNB

ƒ

(29)

Message Queues

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

ƒ Cmd = IPC_STAT, IPC_SET, IPC_RMID

ƒ msg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytes

ƒ euid = msg_perm.uid or msg_perm.cuid, or superuser

ƒ msg_qbytes set only by the superuser!

(30)

Message Queues

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);

ƒ ptr Æ struct mymsg { long mtype; char mtext[XXX];}

ƒ IPC_NOWAIT bit in flag – non-blocking flag

ƒ errorno = EAGAIN if it is specified, and the queue is full.

ƒ Otherwise, it is blocked until (a) there is room left

(b) the queue is removed (EIDRM) (c) a signal is

(31)

Message Queues

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);

ƒ nbytes > msg length

ƒ MSG_NOERROR bit in flag Æ truncate the msg!

ƒ Otherwise Æ errono = E2BIG, and the msg is left in the queue.

ƒ type == 0 Æ the first msg

ƒ type > 0 Æ the first msg with the type

ƒ type < 0 Æ the first msg with the smallest type value <=

type

ƒ IPC_NOWAIT bit in the flag

數據

Updating...

參考文獻

相關主題 :