IT代写 a file object represents an opened file

a file object represents an opened file
a file descriptor is simply an index to this array
Whenever a process requests a new file descriptor, the lowest numbered file descriptor not already associated with an open file is selected; thus
#include
#include

close(0);
fd = open(“file”, O_RDONLY);
the above will always associate “file” with file descriptor 0
(assuming that open() succeeds)
You will need to implement the above rule in the kernel 2
assignment
321 0
Operating Systems – CSCI 402
Allocation of File Descriptors
For each process, the kernel maintains a file descriptor table, which is an array of pointers to “file objects”
14
Copyright ý . Cheng

close(1) removes file descriptor 1 from extended address space
file descriptors are allocated lowest first on open() extended address space survives execs
new code is same as running
% primes 300 > /home/bc/Output
321 0
Operating Systems – CSCI 402
Running It
if (fork() == 0) {
/* set up file descriptor 1 in the child process */
close(1);
if (open(“/home/bc/Output”, O_WRONLY) == -1) {
perror(“/home/bc/Output”);
exit(1); }
execl(“/home/bc/bin/primes”, “primes”, “300”, 0);
exit(1); }
/* parent continues here */
while(pid != wait(0)) /* ignore the return code */
;
15
Copyright ý . Systems – CSCI 402
I/O Redirection
% primes 300 > /home/bc/Output
The “>” parameter in a shell command that instructs the command shell to redirect the output to the given file
If “>” weren¡¯t there, the output would go to the display
Can also redirect input
% cat < /home/bc/Output when the "cat" program reads from file descriptor 0, it would get the data bytes from the file "/home/bc/Output" 16 321 0 Copyright ý . Systems - CSCI 402 File Descriptor Table A file descriptor refers not just to a file it also refers to the process¡¯s current context for that file includes how the file is to be accesses (how open() was invoked) cursor position / file position next location (zero-based array index) to read/write initialized to 0 when a file is opened 17 321 0 Copyright ý . ¡¯s say a user program opened a file with O_RDONLY later on it calls write() using the opened file descriptor how does the OS knows that it doesn¡¯t have write access? stores O_RDONLY in context if the user program can manipulate the context, it can change O_RDONLY to O_RDWR therefore, user program must not have access to context! all it can see is the handle the file handle is an index into an array maintained for the process in kernel¡¯s address space 321 0 Operating Systems - CSCI 402 File Object Context (or "execution context") information must be maintained by the OS and not directly by the user program in this class, we will say that a file object is used to maintain the context information about an opened file in addition to cursor position, a file object must also remember how a file was opened 18 Copyright ý . -Descriptor Table Operating Systems - CSCI 402 File descriptor User address space File-descriptor table (per process) this is yet another pointer "cursor" 0 1 2 3 ref count access mode file location inode pointer n-1 Kernel a file object system file table (system-wide) User context is not stored directly into the file-descriptor table one-level of indirection 19 321 0 Copyright ý . Systems - CSCI 402 Ch 2: Multithreaded Programming http://merlot.usc.edu/william/usc/ 20 321 0 Copyright ý . Systems - CSCI 402 Overview Why threads? How to program with threads? what is the API? Synchronization mutual exclusion semaphores condition variables Pitfall of thread programmings 21 321 0 Copyright ý . Systems - CSCI 402 Concurrency Many things occur simultaneously in the OS e.g., data coming from a disk, data coming from the network, data coming from the keyboard, mouse got clicked, jobs need to get executed If you have multiple processors, you may be able to handle things in parallel that¡¯s real concurrency/parallelism If you only have one processor, you may want to make it look like things are running in parallel do multiplexing to create the illusion as it turns out, it¡¯s a good idea to do this even if you have only have one processor The down side is that if you want concurrency, you have to have concurrency control or bad things can happen 22 321 0 Copyright ý . Threads? Operating Systems - CSCI 402 Many things are easier to do with threads multithreading is a powerful paradigm makes your design cleaner, and therefore, less buggy Many things run faster with threads if you are just waiting, don¡¯t waste CPU cycles, give the CPU to someone else, without explicitly giving up the CPU Kernel threads vs. user threads basic concepts are the same can easily do programming assignments for user-level threads that¡¯s why we start here (to get your warmed up)! for kernel programming assignments, you need to fill out missing parts of various kernel threads 321 0 23 Copyright ý . Simple Example: rlogind requests responses Operating Systems - CSCI 402 Client Server (viterbi-scf1.usc.edu) pseudo- terminal network l_in rlogind l_out r_out r_in Copyright ý . Cheng 24 321 0 Operating Systems - CSCI 402 A Simple Example: rlogind requests responses Client Server (viterbi-scf1.usc.edu) network l_in rlogind l_out r_out r_in pseudo- terminal socket for a socket, l_in = l_out, i.e., you read and write using the same file descriptor 321 0 25 Copyright ý . Systems - CSCI 402 Life Without Threads logind(int r_in, int r_out, int l_in, int l_out) { fd_set in = 0, out; int want_l_write = 0, want_r_write = 0; int want_l_read = 1, want_r_read = 1; int eof = 0, tsize, fsize, wret; char fbuf[BSIZE], tbuf[BSIZE]; fcntl(r_in, F_SETFL, O_NONBLOCK); fcntl(r_out, F_SETFL, O_NONBLOCK); fcntl(l_in, F_SETFL, O_NONBLOCK); fcntl(l_out, F_SETFL, O_NONBLOCK); while(!eof) { FD_ZERO(&in); FD_ZERO(&out); if (want_l_read) FD_SET(l_in, &in); if (want_r_read) FD_SET(r_in, &in); if (want_l_write) FD_SET(l_out, &out); if (want_r_write) FD_SET(r_out, &out); select(MAXFD, &in, &out, 0, 0); l_in r_out rlogind l_out r_in pseudo- terminal if (FD_ISSET(l_in, &in)) { if ((tsize = read(l_in, tbuf, BSIZE)) > 0) {
want_l_read = 0;
want_r_write = 1;
} else { eof = 1; }
321 0
} 26 Copyright ý . Systems – CSCI 402
Life Without Threads
if (FD_ISSET(r_in, &in)) {
if ((fsize = read(r_in, fbuf, BSIZE)) > 0) {
want_r_read = 0;
want_l_write = 1;
} else { eof = 1; }
}
if (FD_ISSET(l_out, &out)) {
if ((wret = write(l_out, fbuf, fsize)) == fsize) {
want_r_read = 1;
want_l_write = 0;
} else if (wret >= 0) {
tsize -= wret;
} else { eof = 1; }
}
l_in
l_out
rlogind
r_out
r_in
pseudo- terminal
if (FD_ISSET(r_out, &out)) {
if ((wret = write(r_out, tbuf, tsize)) == tsize) {
want_l_read = 1;
want_r_write = 0;
} else if (wret >= 0) {
tsize -= wret;
} else { eof = 1; }
} }
}
27
321 0
Copyright ý . Systems – CSCI 402
Life With Threads
l_in
l_out
incoming(int r_in, int l_out) {
int eof = 0;
char buf[BSIZE];
int size;
while (!eof) {
size = read(r_in, buf, BSIZE);
if (size <= 0) eof = 1; if (write(l_out, buf, size) <= 0) eof = 1; }} }} don¡¯t have to call select() Copyright ý . Cheng r_out r_in outgoing rlogind incoming pseudo- terminal outgoing(int l_in, int r_out) { int eof = 0; char buf[BSIZE]; int size; while (!eof) { size = read(l_in, buf, BSIZE); if (size <= 0) eof = 1; if (write(r_out, buf, size) <= 0) eof = 1; 321 0 28 Single-Threaded Database Server Requests Operating Systems - CSCI 402 Database 29 321 0 Copyright ý . Database Server Requests Operating Systems - CSCI 402 Database will be very difficult to implement this without using threads if you want to handle a large number of requests simultaneously 321 0 30 Copyright ý . Systems - CSCI 402 2.2 Programming With Threads Threads Creation & Termination Threads & C++ Synchronization Thread Safety Deviations 31 321 0 Copyright ý . Cheng it¡¯s like main() for the child thread the "thread ID" of the newly created thread will be returned in the first argument of pthread_create() Operating Systems - CSCI 402 Creating a POSIX Thread man pthread_create SYNOPSIS #include int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg);
Compile and link with -pthread.
the start_routine is also known as the “first procedure” or “thread function” of the child thread
may not be a Thread Control Block Copyright ý . Cheng
321 0
32

Creating a POSIX Thread
start_servers( ) {
pthread_t thread;
int i;
for (i = 0; i < 100; i++) pthread_create(&thread, 0, // default attributes server, // first procedure argument); // argument of first // procedure child thread starts executing here arg = argument (from caller) child thread ends when return from its start routine / first procedure } void *server(void *arg) { // perform service return(0); // thread ID Operating Systems - CSCI 402 } pthread_create() returns 0 if successful POSIX 1003.1c standard pthread is a user-space library package threads in a process shares the address space 321 0 33 Copyright ý . Cheng } void *server(void *arg) { int k=(int)arg; // perform service return(0); } stack frame of start_servers() stack frame of main() Operating Systems - CSCI 402 Creating a POSIX Thread start_servers( ) { pthread_t thread; int i; for (i = 0; i < 100; i++) pthread_create(&thread, 0, thread, i 0 ... argc, argv server, (void*)i); every thread needs a separate stack first stack frame in every child thread corresponds to server() one arg in each of these stack frames 321 0 stack space 34 Copyright ý . Cheng } void *server(void *arg) { int k=(int)arg; // perform service return(0); } stack frame of server() stack frame of start_servers() stack frame of main() Operating Systems - CSCI 402 Creating a POSIX Thread ... arg thread, i 0 ... argc, argv start_servers( ) { pthread_t thread; int i; for (i = 0; i < 100; i++) pthread_create(&thread, 0, server, (void*)i); every thread needs a separate stack first stack frame in every child thread corresponds to server() one arg in each of these stack frames 321 0 stack space 35 Copyright ý . Cheng