compsci(2008)
Tue 01/22/08
the joy of c
lab reports due the next wed
ost - operating systems today
g:\pankdc\cs370
cof112
Solaris
C
everything returns a value
everything is an expression and all expressions return a value
if (x = x+1)
no bool
0 means false, to C and anything other than zero means true
#define .. i want this symbol to mean this
define TRUE 1
define FALSE 0
int i; //can we comment this way?
/* standard C comments */
for, if..else all the same
printf .. like cout, but lets you format
printf goes to the standard output device .. usually your screen
(how, what)
% = put the number here
2 columns
two % .. you can have it appear twice
%s string
%c printing out a char
C book chapter 22
printf returns an int .. will return how many numbers it successfully printed
Fact 2.
All function arguments are passed as value arguments compared to reference args
int scanf(format, parameters)
INT .. REPORTS BACK NUMBER OF SUCCESSFULL INPUTS
YOU'LL GET A -1 IF IT FAILED ON FIRST INPUT
int x;
char ch;
int n;
n = scanf("%i%c",&x, &ch)
how, where to put them
if you put a space, then must type one
copy a file char by char
FILE *fin, *fout;
if ( (fin = fopen("source.txt", "r")) == NULL)
{
/*trouble*/
return -1;
}
out the same way
int a[3], *ip;
0100 - *ip
5000 - 5 a[0]
5001 - 18
5002 = 7
a is an address
&a[0]=a
a+1 is an address .. and that's probably not 5001 .. depends on the size of the element
ip = a;
*ip == a[0]
ip++;
*ip == a[1]
a++ a==a[1]? no! .. you can't change where the array starts .. it's a constant
reference arguements and funtions
int main {
int x = 2000
increment(&x);
void inc(int *x) {
(*p)++;
return;
}
structs
struct snoop {
int a;
int v;
};
unix kernal
get status
----------
| |
----------
snoop
---------
| ---- |
| | | |
| ____ |
| |
| ---- |
| | | |
| ____ |
---------
prototyes
snoop getstatus();
iset space
#include sniff.h
snoop x;
x = getstatus();
printf("%i\n",x.a);
go inside a struct by using a .
snoop * peekatstatus();
//returns a pointer to the data
but usually you don't get that either
const snoop * peekatstatus();
doesn't mean that the pointer can't be modified but rather what it reeturns
snoop x;
may be at 100
x = *p; /*does a block copy for me*/
x.a++;
==========(Note Break)==========>>
Thu 01/24/08
lab1-5. .. do on your own project
History
-------
Hardware + Software - os and apps
software generally lags behind the hardware
hardware change -- a new invention -- probably modifying existing software .. the same thing in better time
software reaches maturity and you start streching the hardware -- hopefully you get another hardware generatin at that point
1st genoration: 1945-55
vaccum tubes and plug boards .. that's how you programmed
plug board - 1 instruction per board
taylor series
e^x = 1 + x + x^2/2 + x^3/(2*3) ....
compute that on first gen
exp = 0
term = 1
n = 1
do
exp = exp + term
term = term*x
term = term/n
n=n+1
loop
step-step-step .. too slow .. not a good use of the CPU .. because you're pressing step.
optimize usage of the CPU
2nd generation: 55-65
transitor .. smaller and faster -- no heat and cool time
in the os -- batch systems
resident monitor in memory -- that could sequence through statements
we also had a stored program -- not on big boards anymore .. in magnetic coils .. little magnetic cores, as they've called
there was some memory to store instructions .. RM would go through the instructions one at a time
called batch because things were either run with punch cards or on reel to reel .. and you needed a compiler of some sort .. to get things to compile, you'd run them through a compiler first .. and you needed the complier in memory to compile
as long as it was in memory, we ran all fortran jobs at the same time -- therefore the term batch
(batch today means non-interactive)
punch cards -- got the forms for the programming language --- in column 1, meant yo had a comment, etc
wrote programs on paper first, handed them in and they would make punch cards out of them
but the typist didn't know about programming so they put slashes through 0's and lines through z's
you would not be allowed in the room when the program was executed
you'd go to the desk and find job control cards -- you're not going to be around when the program is run so you have to indiicate comiler, data, card reader -- do you want the output to the tape or printer (name please) and those commands began (IBM's version) began with a slash .. \\job
because the card hopp would have evryone's program queued up
//fortran
//load
SNC was doing this until 1980. they were the first private school to have a mainframe for education perposes .. got an nsf grant for that
3rd generation - integrated curcuit and multi programming operating systems
IBM was big in this market -- IBM 360 .. then 370
IBM always tried to take care of the legacy
Fred Brooks - was in charge of the os .. wrote a book about it .. mythical man month
multiprogramming - more than one program in memory at a time ..
and the OS is more complex -- we don't want program 1 interfering with p2's memory space
also called multitasking
nice feature -- multiple programs pseudosimotaneously .. remember, one CPu
OS -- gives the cpu to one of the programs
not just going down the programs
operating system in charge of which program gets the cpu
so if it gives it to p1 .. eventually p1 is goin to need to do some i/0 .. gonna run a driver -- that's outside the cpu .. the cpu will sit idol
operating systems are built to own the divices .. so the OS definitely knows that the program wants to print
so it says "alright, I'll schedule p2"
time sharing .. you can't be a cpu hog -- everybody get's a shot at the cpu , so every program gets to make some headway
so if p1 is paused for printing and the os says i'll give the system to p2
and p2 is ding a bunch of graphics ..
so p1 gets done printing and so p1 is ready to go again
and p3 hasn't done anything yet
so we're going to put a clock in the system and each process gets a time slice
and when your tinme slice is up, the OS will rip the cpu away from you - not always a very safe situation -- you shouldn't get ripped away at a critical moment .. but it might make things more fair and get more work done overall
each of thse programs probably run slower than if they could do it by themselves but the overall amount of work is greater
tso - time sharing operating systems
interactive = the computer has no clue what you want because you have no clue .. you can make it up as you go -- and that's harder on the os - different management issue .. os doesn't have a method of throttling how many processes should be in there -- we throttle it ourselves - "i'll check my email later"
4th generation -
==========(Note Break)==========>>
Tue 01/29/08
3rd generation -- multi-tasking
take seeral jobs and the os schedules on of hhem for the cpu and then usually a program is ding i/o and therefore doesn't have much ese to do so the OS will get notification of that because it's in charge .. you can't just activate the printer - you have to request a print .. and then puts the program to sleep (takes away the resourses temporariily) takes the cpu and scheudles another porcoess at that time
how do you do that?
several different ways
basic way:
overlapping cpu & I/o operations
same computer (with one processor) .. can use DMA (direct memory access) works with disk and memory
the disk controller will have some smarts to it that can move info back and forth from memory and disk without the cpu having to be involved
disk controller if it has some smarts, the cpu could schedule the controller to say "when I'm not using the bus, you can steal some bus cycles from me and move blocks of moemory"
can do that a char at a time or a byte at a time
block movement .. cpu lets the disk use the bus for an amount of time, but cpu can't get any work doen at that point
we're overlapping processing here ..
topics have a way of coming back.
if the cpu is fast enough, why are you doing this in the first place
5.1.4
other way of doing this is iterrupts
review of interrupts at 5.1.5
buffering is tied to interrupts
overlapping i/o with the processes own computation
device driver
doing a read command ..
if we don't have buffers, i nedd to go into a wait stage until the driver delivers info .. then i can go again
if I had something i could be doing instead of waitng, then i'm kinda scrwed because there's no place for the data to go except to the program.
what could happen is the driver could issue an interrupt .. when the data arrivs, the driver could interrupt the process and say "here it comes"
the problem with that in a multiprocessing envronment is that when the data arrives, the process might not be there -- it might have been swapped out
so instad, use a buffer --the driver would deposit the information in a buffer and then when the process was ready, it would pick up the info from the buffer
you can't just read the information from the buffer when you want to because there may be information in there that you've already read, so the concept of the interrupt still works pretty nicely
so the buffer is probably owned by the OS kernal
double buffering
somewhat more complex .. which buffer is active .. is it empty, is it full
so the buffer software is more complex
buffering helps a little bit, but you're usually waiting anyway
buffers used a lot in networking
spooling .. another technique .. page 12 def, 359 example
process and you need to print stuff
not going to print to the printer at all, but to the disk.
process 1 prints to disk
and process 2 prints to disk
and the spooler is a process that's always running ... daemon
so the spooler gets the lazer
what made this work was disk -- this wouldnt work on a tape
also have job/program spooler
.. loading processes and the spooler picks which goes next .. sometimes takes the small ones first, etc
buffering .. among it's own computation
spooling .. amoung different processes
page 3.
def of OS:
gobetween for the user -- graphical shell
abstraction for programs
cout << vs talking to the hardware
firmware is also part of the OS
multi-threaded programming
1.7 structures
monolithic - the OS is one program .. and it has a main and a lot of functions
memory laid out as
user space or protected space
anytime a process tries to do something with memory, the OS checks on it and sees if that's OK .. are you destroying somethng else .. are you trying to use the printer port when you don't have access
kernal mode aka supervisor mode
that runs trusted code .. code that is correct .. that won't screw up something.
if you're root, you can be let into kernal mode
monolithic
main function that gets information frm th processors and decides who needs to do the wwrk
there might be a scheduler a emmory manager, file manager, disk manager, audio card manager, process manager -- decides who goes next
if p1 decides to issue a read, it goes to the main with it's arugments
if you install a new driver, you have to restart the OS
issue read, the main grabs it, and then the main deals with the read funtion
on the other side of things: client/server
more modern operating systems
neolithic
kernal mode
user mode
program sends a message to the kernal .. the kernal may end up being a message passer
process can say "make the audio card do this" and the kernal can say "no"
so it runs protection so that user moduales don't get into trouble
if you screw up something in one part, it doesn't bring everything down. but it has more processes in the user mode
kernal has the clockf .. a lot of things are syncronized ... so not everything is in user mode .. and it does run protection so that modules don't run on things it shouldn't
registry - keeps track of what programs can do what
virtual OS .. not really real
piece of software -- kypervisor .. sits on the hardware .. deals with the hardware, specifically the cpu
and above there, you load vista, or linux, etc and you can run applications
.. and it translates the instructions to the necesary hardware
hardware has to allow virtual system calls.
actually an interrupt that gets executed that switches you from user mode to kernal mode
another solution: type 2 hypervisor
your computer with your OS and run this on top of it .. VMWare .. a type 2 hypervisor .. you dn't have to make it happy with the hardware directly,
you can load windows or whatever you want
example:
windows as your host, linux as your guest .. but you can still have you windows apps
unix file manager
I/O using files
C : file pointers (file *fp)
unix uses file descripters ... (int fd) Wang 11.1
these are device independant i/o
we can use some C wrapper funcs to get at the unix stream i/o
open()
close()
read()
write()
fctrl()
all I/o is in binary
usually we do block movement
a write will take something from memory and put it on a device
a read with take something from a device ( a block of bytes) and put it in memory
binary mode.
if (if (df = open("/tmp/foo",O_RDONLY)) = -1)
then we had issues
printf(stderr, "can't open");
stderr is not buffered
exit(123):
O_WRONLY
O_RDONLY
page 330 wang? king?
file description table
table of ponters
0 --- std input
1 - std output
2 - std error
3 - fd .. points to our file foo
fd will get an entry into the table
how does it point to foo
file descripter table .. you get one for every process you write
those points point into kernal area
system file table .
each active open has an entry
file ponter .. access type
some one else may have a file descriptor table and have foo open
they have their own entry in the system file table
that all points to
in memory i-node table
there's an inode for foo
has size, permissions, time created, time modified
counter .. and other things
stat() will give this infoin our situation, the counter is at 2 -- two users using that file
if we don't have a good exit of the progam, it may leave entries in the table
so you need a garbage disposal
last guy out will remove the entry from the i-node table
files in C
FILE * fp;
if ((fp = fopen("foo", "rw")) == NULL)
{
error
}
fprintf(fp, "%i", 66);
gets buffered
goes when the buffer fills
calls the unix write command
fflush(dp);
printf .. really fprintf to stdout
stdout is line buffered
will committ to the screen at an EOL
scanf works the same way
==========(Note Break)==========>>
Thu 01/31/08
int df = open("foo", how);
read (df,0 - stdin device
1 - stdout
2 - stderr
so 3 points to the file foo
so read (0, ----)
would read binary from the stdin
n = read (df, "where", how many);
n = number of bytes actually read
0 if you reach EOF
char buffer[100];
n = read(df, buffer, 50);
sum = sum + n;
.. count how many bytes in the file
do it byte by byte --
n = read(df, &ch, 1);
if it's greater than 0 we're ok .. when it equals zero, then we're done
char * buffer
an address to bytes
printf("%s",buffer);
.. but that goes until you hit a null
lab2-5 on g:
.. take two weeks
when i/o happens , you can schedule anohter process
what does that mean?
handout
handout page 2
suppose an app issues a read
read is a call .. goes into kernal mode .. looks up where the function exists
step 2 - driver looks at the status of the control unit -- idol or busy
while (comm1:deviceController.status = 1 .. while it's busy
cpu is executing our busy wait loop
sooner or later, the stattus changes -- it'll issue a comand to the controller
4 - waiting for the status again
the status changes from idol back to busy as it does my job
so, step 4 is another busy wait loop
eventually the status goes to idol again -- the data has arrived from the device to the controller
delivered to the read .. and control is passed back to the major funtion .. so basically it executes a rturn statement
this is called programmed i/o
the driver could have been built into the program
the downfall is that the cpu basically stays with me and a lot of times its idol
easy .. but we're not using the cpu to its advantage and not doing a lot of work
page 4. the difference between this and the last one is that we can also do interrupt i/o if the system allows it
we issued the read command and as we issue the read command, we are put to sleep .. suspended
it's gonna take some time to deliver the data .. so if your next command is to use the data .. you better not do a non-blocking .. you need the dta
so if you had something else to do , fine .. usually you need to sleep here
the read then as before basically checks the status
we could use a busy wait loop but that would tie up the cpu .. so usually the read puts itself to sleep .. and what we might do is schedule another prcess .. so give the cpu to some prcoess that isn't waitnng for something
eventually i'm going to get my turn again -- a signal would be sent here when the status turns from busy to idol
and signals are intersting things .. they're like ringing the phone ..
ctrl-z , kill .. the OS acts on that signal as soon as it gets it
once it gets the signal , it wakes up again
so the other job that we switched to gets suspended and we come back to our process
the time consuming is when you go to he device and get the data .. so a lot of systems bust up the startup of the driver and when the data arrives -- into two parts
information needs to be savd .. so that get's stored in the device status table
how much we were reading at a time would alss be stored there
so then the open side is done -- it ends
and at this point the os does indeed schedule a different process .. this is like waiting alomost a year compared to what the cpu could be doing
so here's a bunch of time that we'd be sitting idol
eventually the dta arrives
how is the operating sytem gonna know that we're ready to go again?
well, it issues an interrupt .. and so the os will know that it has the data -- the interrupt handler is actually executed by the cpu -- it stops what it's doing to execute the interrupt hhandler and deliver the dta
the application could be sleeping yet
we get things started and when the status says ok go .. then we can schecule a different process
process b executing .. got the cpu .. interruut happens .. whatever the cpu is donng , it stops and it executes the handler -- hardware mechanism ..
handler brings it out of the buffer and brings it to the process .. cpu does that .. done with the interrupt
what does it do then? the process that was put on hold gets to go back .. but our first process was ready to go .. but that doesn't mean he's going to go
could he go? yeah .. if the os is programmed to give our first process priority, then it might start it out again .. but it doesn't have to
so there's two different going to seleep -- the os and the interrpupt hardware action
but there are some yeahbuts .. what if the process is swapped out? .. it may sit down here for awhile
might sit out for awhile .. buffers are good things to have
page 3 -- we're not really going into that level .. but that explans more about interrupts
page 5. trap instruction
code inside read command
puts the id of the kernal call usually in a cpu register ex: ax register
moving to trusted code
thre's no way i can call the read driver myself
in order to execute cde in supervisor space is to have the mode bit set
that's set by the trap .. interrupt 80
looks at branch table
so all of a sudden i've left user space and i'm over in supervisor space
brnach table looks up the command and it wwill go over and execute the code ie, read command
branch table - table of pointers to kernal drivers
"trap over to kernal mode"
usb drivers have to be user mode?
last page: reconfigurable device drivers
==========(Note Break)==========>>
Tue 02/05/08
FDT
0
1
2
used by stdin, stdout, stderr
fdt .. pointers to information on the different file streams
3 can point to information about "foo"
i/o is a good candidate for multitasking because
A: - diff process than the cpu
b: interrupts are good at decoupling
c: gotta wait for i/o anyway
dma .. uses interrupts
sum = 0;
cnt=0;
while (....
lab1
simpbiff 30 &
ls -l
--> the -l is an arugment
unix puts these arguments in a process control block.
.. an area that the OS maintains info about the process as it is running
FDT is here
int main(int argc, char *argv[])
argc --> number of args on cmd line, including the process name
so mv a.out biff.bin has 3 args
array of pointers to characters
so, argv .. the first pointer points to the first string
2nd one pints to the next one, a.out and makes a strihng out ofit
and the last one points to a null
--> strtok
biff.bin 30 &
sleeptime=60
if artgc > 1
** & doesn't count
{
sleeptime = atoi(argv[1]);
but you need to check if it's valid or not
lab2 - printout of the functions ...
environment variables
global vars that
belong to the shell and all progs that run in the shell
way of getting information from open program to another
we can edit .profile
echo $CLASS
shows what's in the CLASS environment variable
env shows common environment variables
set tells all of them
ps1 .. decides what teh bash prompt looks like
PS1='$PWD';
some shells make you export it before it sticks .. bash doesn't but do it anyway
export variable name after you define it
can write programs based on if a variable exists or not
wang 10.1
int main(int argc, char* argv[], char*environ[])
so you also get an array of pointers to environment variables
an array of pointers to strings
getenv("MC");
so we can get the mail directory for our simpbiff
no spaces right after the = sign!
str = getenv("MC"); .. str is pointing to the string
need to use strcat to concat
strcopy
strlength
char mybike[100];
strcopy(mybike,str); copy str into mybike;
can't say mybike = str;
strcat(mybike, "is fun");
DACs .. Data Acquisition system
usually analog
need an analog to digital (A/D) converter
device -> acd --> collect process
process has to be quick s that you don't miss a sample
--> statistics/math module
-> log ... controller that writes to a file of some sort
reporting mechanism -- speaker blows a horn sayiig that the machine is out of alignment
how can we do this multithreaded
while it's printing, we can use the cpu
we could collect an dlog at the same time? well, you have to colect before you log, but we could buffer what we collect (can use interrupts to tell buffer status)
collect puts informatin in the buffer and log rads information out of the buffer when it needs it
alos, status, you can read out of the buffer, tooo
reading doesn't necesarily mean removing, so they both could read ouu of the buffer
but you'll have to signal collect that it's ok to put a new value in
buffering will help
do log and stats depend on one of them going first ? is the ordering hhere necessary? probably not
priority will be an issue as well .. when things are sleeping and things can be scheduled .. who do you schedule if there's a tie? .
how cpu hunger are these processes?
stats takes cpu all the time -- all computation
meet in 203 tomorrow.
==========(Note Break)==========>>
Thu 02/07/08
name two ways that different progrmas can exchange info:
- environment variables
- command line arguments .. as I launch, i caa give it some information
process management: (chp 2)
facts:
- a system has two software entities: files and processes
files are programs at restprocess is an active program .. an instance of a prog that is running
Peter Denning's Def:
OS = computer system software that assists the hardware in performing process management :
1 creating and deleting processes
creating -- find room and asiign resources, destroying -- delalocating the memory space, taking resources away -- shutting down .. shut it down before it actually terminated .. gracefully do what you can for it
2 controlling the progress of a process
the goal of a process is to do its work -- and one of the jobs of the os is to assist that it does that
we have multiple processes and just because you want to run doesn't mean your going to be allowed to run .. but you should run enought to get something done
each process makes progress at a positive rate
3. acting on exceptional conditions .. interrupts, events, signals,
4 allocating resources to processes and providing the means of inter process communication (IPC)
.. in our dac, it was an "it's ok to go" signal
creating a process:
the user can do it from the shell .. just give the program name followed by command line arguments and hwen you hit henter the loader grabs it and put it in memory
another is under program control .. a function call that creates a process --> create process, exec program name
system(program name)
exec usues the same meory space as the program that's executing
system creates a new shell and then runs the rpogram and then destroys the program in that shell
generally we set up children to do the work --> like our dac system
3 states
a process when you create it, it is always ready to run -- it goes in the ready queue
scheduler decides who wants to go .. priorities
then we can move to suspended, aka sleeped or stoped.
if you have high priority, you can pre-emp what's running
only 1 process has the cpu unless you have multiple cpus .. then you have it for each of the cpus
either running or ready to run
or you're waiting .. you chould use the cpu even if it was given to you (waiting for collect) .. out of the scheduler
quantum .. period of time that in some systems .. the cpu says "if you're a cpu hog, i'm not going to let you have it forever.
processes in comepetition
they're hungry for the cpu .. also for memory possbily or for dvd read or write
cooperation:
collect, stat and log we're cooperting .. idea of syncronizing activities and sharing resources
--> programmers set this up
.. we didn't know inherantly that we couldnt read from the buffer -- programmed into the process
multi-tasking can be explicit, like the DAC
we specifically say how it goes down .. more throughput
or it could be implicit .. we do nothing as a programmer .. we launch the programs and multi-tasking will happen
oars used explicit mult-tasking
you can't think sequentially
each process has a process control block as an entry in the process table
process table
pid
the pid could be the number in the array
if i create aaprocess, the process control block ins in the array
all the information about the runnihng process
pcb .. a lot of information abou the rpcoess right now
and each instance has it's own pcb
pcbs need to be updated when you have a state change -- moving from ready to running for example
if you're going to sleep, it needs to update everything
if you're going to be swapped out , then it has to know here you rfiles are
the cpu saves the return command but not anythin else
so it's the os job to save all the registers and such
the amount of information that's saved is costly
this is overhead -- the cpu is active in all the transfer stuff
you want to do process switching, but you want to keep it kind of minimized
so if you've got the cpu, you should keep it unless the process is being a hog.
but you gotta at least show that everyone is making process
Process switch (Pswitch)
.. context switches
takes time .. baulky
threads -- software solution
lightweight processes
reduced overhead .. smae memory space as the process.
might think of it as a function .. has code, local variables, and a local stack. .. part of the thread it's code and the functions that it calls
a thread has emory but it doesn't have other resources
.. those belong to the process
. on a thread switch, it's basically the cpu registers and the local variables
only a dozen or so parameters that need to be save.
DAC system -
dac process
collect thread
stat thread
report thread
log thread
buffers - like global variables
thread:function::buffer:global variable
they share files as well
so collect chould easily tak to the buffer and stat and log could too
easy to program because they can see each other
you can bounce between them without much of a problem
but they don't own any hardware
only code -- thiink of them as a function
so, thread switch easy, process switch .. not
Office running with some threads
spell check
autosave
etc
if you do a process switch, you leave all the threads in DAC and schdule amoung the word threads
if the os can only schedule by processes, then when a thread goes to sleep, the whole process goes to sleep.. windows supports it, linux does, unix in general does not
scheduled threads in linux:
kernal will have a process table and a thread table
and information about which process the thread belongs to
so the kernal can say that we have to put the report to sleep but we can schedule amoung any other threads . but not necessarily the same process
java is thread based.
you can do threads in c++ as well
in a lot of systems where you see threads, they're compiler based -- the os doesn't know about them
so if they're comiler based
then process x has a protion with a thread table and a scheduler
thread0, thread1, thread2
and when process x is executing, the thread module decides which thread get the cpu
and the kernal just knows about the two processes we launched .. knows nothing about the threads
so the kernal can put a process to sleep because the thread does I/O .. all the other threads go to sleep then
threads in general suffer from stupid programmers
the data is shared .. global variables
so if you've got two things updating the same info, you might have an issue
or two threads doing a cin
the programmer has to look at sychrnoization issues and put them in the code
book: all kinds of threads and things that can go wrong.
==========(Note Break)==========>>
Tue 02/12/08
busyy wait loop
collisions
if we have to handle these sequentially -- we're in trouble
threads, multiprocesses
create popup thread when clients come in
what happens when you recieve a message while you're handling something else
right now it's just lost
web servers, too
while(1) {
client = waitmail():
create a thread (client id);
}
when the thread is done, it destroys itself -- "free up this memory space
you do have overhead in the creation of the thread, but that's short compared to actually handling it yourself
threads are living in your process space - given only suo much memory, so there's a maximum number of threads you can spawn
sometimes there a queue that builds up
how unix creats processes from processes
creating prosesses
uncer program control
- exec();
system();
fork();
today -> fork();
unix creates a new process using fork().
forker is the parent and the forkee is the child
parent has control over the child
after the fork, there are two identical processes except for one thing: ___
the child is a clone of the parent
gets the same coee, data, stack, process control block
everything that existed up to the fork , before the fork, is copied .. may differ after the fork
process
--------
file descriptor table
code
and then there's a fork
at thh fork, a child is created and it does a memcopy - a memcopy is a binary copy -- you get a separate address space with a new process and new processs id and it shares everything -- everything that went on before is the same.
but after this, these are multi- tasking .. they'll both get to this code down here, but I can't tell who's going to get hhere when.
what about pointers? well you probably are pointing to the same place on the heap
process b -- we don't know of it by name because it never sits on the disk - the system assigns a unique process id to it
ps -f will show the parent
so here's the except for:
fork() if it doesn't work out returns a -1
if it does work out , it returns the pid of the child.
the parent has a handle on the child.
child gets 0
so i can tell the different -- if a is zero, do this, else to that.
if parent or child opens a file after the fork, it isn't shared.
so they can read the file independantly
if a file is open before the fork, the two processes share the file pointer.
if we look at an open statement before the fork, they have the same pointer to the file in the system table.
so if the parent moves the file pointer along, the child reads from where the parent left off.
the disk and the file manager thingks that there was only 1 open statement that was executed
so if one closes the file, the physical connect is removed. pointer hanging in the table of the fork
open a file after the fork -- as if two separate programs are reading the same file
create some processes using multiple forks
example
int x;
x=0;
fprintf (stderr, "%d\n",x++);
fork();
fprintf(stderr, "%d\n",x++);
fork();
fprintf(stderr, "%d\n",x++);
so what do we get
0 for sure
then we get a fork (child)
eventually 2 1st come out on the screen
someday, both the x's get to 2
chain
-----
for(i=1;i<4;i++) {
if(fork())
break;
}
remember fork() returns 0 for child and pid of child for parent
so the parent breaks out of the for loop
O --> O --> O --> O
four processes running, chained together in terms of hierarchy
for (i = 1; i < 4; i++) {
if (!fork())
break;
}
known as a fan
in unix, child gets the same priority as parent
windows --> you can assign thread priority
when a chld's done, coe, stack, data, files(maybe) are deallocated
and the aprent is sent a signal (sigchild)
but the child still exists as a zombie
thie child's pcb still exists i thh process table, but there is no process for it but it's taking up an entry
if a parent dies before the child, the child lives on as an orphan
all orphans are adopted by init() (pid=1)
init() waits for all its children to signal it
it will remove the processes from the process table
a parent can wait() for it's child to signal it when signaled, the zombie is removed from the process table.
pid = wait(&status);
^-- pid of child
parent waits here for a SIGCHILD
so if you need 3 children to finish, you need 3 wait statements
status - 16 bit variable - on the rigth = signal # of what happened to the child.
did the chld terminate normally? -- if so, a zero will be there
otherwise, there'll be a code in there for the error number - div by zero, ctrl-c, etc
on the left -- argument from exit
to get at the exit condition
status = status >> 8;
status status & 0x00FF;
pid = waitpid(pid to wait for, &status, options);
so you can wait for a specific child
reports -1 if error -- ie, you have no children
waitpid(-1,& status, 0)
--> wait for any child (same as wait() command)
wnohang -- don't hang around if there's no child that's dead yet
if parent gets any signal, it wakes up the wait
==========(Note Break)==========>>
Thu 02/14/08
Quiz:
1. Can a zombie wake up and restart?
zombie .. dead process
why not? it's pretty much all gone but still in the process table - process control block
2. can a child live if the parent dies?
yes
3. can a child wait for a parent?
no - unless you give the signal yourself.
4. what happens if a parent terminates and doesn't wait for its child
child is an orphan now .. but still lives .. init becomes the parent (adopts orphans
5. if a parent has several children, can the wait function tell which child signals it
yes! wait returns the pid of the child that signaled it
returns status -
one of the things is if the child idd an exit and put a number in the exit or a return, that's reported there
exit vs _exit
_exit just quits -- no housekeeping... doesn't close the files, etc
but a good os does some of this housekeeping
6. if a parent never terminates, what happens to the child when it terminates?
does it stay a zombie forever?!
IPC - interprocess communication
1. How do you pass info back and forth?
2. How to maintain data integrity
2.3
racing conditions
on a piece of data or a resource
two processes or two threads are attempting to modify some informatin and there's a threat of data integrity based on who does what when
critical section , region ---
part of the code that may cause a racing condition
mutual exclusion - no two process are exectugin their CR (critiacal region) at the same time.
good solutions:
1 - solves the mutual exclusion problem
2. all processes make progress toward completion
a) no process running outide the critical region can block others from entering. -- don't open a file at the start of the whole program and close it only at the very end.
b) no process should have to wait a long time
3. hardware independent if possible
a couple solutions
solutions:
switch for a vacant / lock variable.
lock =0 .. vacant
==1 .. busy
while (lock ==1);
lock=1;
accesscriticalstuff(); <-- don't do a lot here
lock=0;
the rub:
again:
cmp [lock],1;
je again;
mov [locj],1;
etc
machine level instructions are indivisible
but you can get a process switch at the end of any line.
what if we get a process switch when lock isn't set yet?
then we both can be in.
so what do we do?
solution next week!
turning off interrupts --> cli
but the os won't let you -- and you can't do i/o
.. and that's a hardware issue!
so we want the os to help us.
most basic was of doing this:
semaphore:
an os concept
can send semphores through the os to each other
comes from flags "in scouts"
ohhk
==========(Note Break)==========>>
Tue 02/19/08
Quiz
----
global buffer int buff[5]
+ a tail int in for inserting new bytes
buff [12][22][][][]
in [2]
give a speciffic example (list execution stems) .. shows this activity can lead to a racing condition
inserting into a buffer can cause data integrity issues
if you do threads, the the buffer would live in your program
P[0] P[1]
buff[in]=78; buff[in]=44
in++; in++
if we had a p-switch righh between the buff statement and the in++
so we overwrite our data in one box and then leave junk in the next box because we still increment twice.
the critical section of code - adding to the buff and incrementing in
process 0
---------
enter_region(0);
buff[in] = data;
in++;
leave_region();
process 1
---------
enter_region(1);
buff[in] = data;
in++;
leave_region();
enter_region will have to look to see if process 1 is executing - if so, it should not let me return
if nobody has executed, go through but set a flag
leave_region - open the door. "i'm done"
see fig 2-24
process zero comes in and markes its
interested, sets turn
if Po goes thru enter_region(0), it set interested[0] = T so that when P[1] enters region, it gets stuck at the while.
leave region - i'm no longer interested -- i'm out of there so when P[0] executes leave region, it sets interested[0] = false, and now P[1] will quit the while loop and entersts the critical region
P[0]
interested=true
P[1]
interested
he who came first is the first one in
more than two - messier than hell...
see tanenbaum
a typical hardware based solution
a cpu solution
not as drastic as clearing interrupts
TSL - test and set block
lock []
0 = enter
1 = busy
enter_region()
{
asm {
busy: MOV AX,1;
XCHG AX, [lock]; --> can't be interrupted there - indivisible
cmp AX, 0
JNE busy
}
Leave_region()
{
lock=0;
}
also, intel command called Lock
and if you have dueal processors, sets the lock pin on this cpu so taat other cpus don't execut this tatement at the same time.
the primative kernal semaphore
DijStra
----
a semaphore s is an abstract data structure that belongs to the operating system (kernal) , has functions/properties
create(s, init_value);
down(s); aka p(s);
up(s); aka v(s);
s has a waiting list, queue of pid's that are blocked by down.
so down is like entering a region
might have the value of s
might have the number of processes that are blocked
might have the process of the last access, time
etc
object - not just an int
down(s)
if (value(s)>0)
s--
else block(s); /*kearnal blocks the process on S. */
queue of the processes that are blocked.
lots of processes participate on the semaphores
then the up method ..
up(s)
if (value(s) = 0 && blockqueue isn't empty)
then wakeup (s); /* chose the pid from the blocked queue */
.. moves it from blocked to ready
not in the ready queu -- won't but woken up by the cpu until it's in the ready queue
which one does it wake up? DijStra doesn't say -- not necessarily the 1st one that was blocked
else value(s)++;
down - blocking
up - freeing
s value can be positive but never negative
a couple examples
synchronization:
---------------
S[2] can execute only if S[1] has executed
P[1]
while(1) {
.
.
.
S[1]
up(synch);
}
P[2]
while(t) {
.
.
.
down(synch);
S[2]
.
}
need a signaling mechanism .. we're gong to use semaphores
create(synch, 0 )
P[1]
----
P[2]
-----
down
Synch
-----
0
we bank the ups
so we used this as a synchronization tool
mutual exclusion problem
critical region like the buff problem
and we'd like to protect it
cr
-
mutex
-
block
-
ready
--
p[x]
p[y]
p[z]
each process goes down on mutex
cr
then up on mutex
all processes start in ready queue
start mutex at 1
0 blocks everyone
2 lets two in at once
on an up -- pz woken up from sleep -- immediately enters cirtical code -- so the region needs to be protected.
mutex can passically only balence btween zero and 1
get cozy with this
semaphore set
create(key, number of semaphore)
create(0x9001, 1)
.. avoid semaphores that unix has
array of 25, -- so I'm wasting 24
mutex index of the array of teh semphore that you want to use
create returns a semid .. that's how you refer to your set.
int mutex = 0;
semaphore_init(semid, mutex, 1);
ipcs - inter process communication shared memory
that'll show you:
semaphores
message mailboxes
shared memory
==========(Note Break)==========>>
Thu 02/21/08
semaphores:
----------
don't do much -- so you can do anythihng with them :-D
- synchronize activities
and on the DAC system we'd use a semaphore for collect and stats when data enters and exixts the buffer
mutual exclusion - mutex .. P[x], p[y], p[z]
protecting critical code
down
critical
up
and set mutex =1 so that the first process can get in
mutex bounces between 1 and zero
another use - to count
the bounded buffer problem . aka producer/consumer problem
example might be a print spooler -
producers: programs that have documents that need printed
think of laser in one of the labs
consumer takes out of the buffer and puts it on the printer
. could have more than one consumer - could have a bank of printers
buff[][][]
n=3
in []
out []
we need a mutex to protect the buffer
and in and out
semaphores:
full = 0 //number of items in the buffer
empty = 3 //number of empty slots
if I'm a producer, I have to pay attention to empy -- in ourder to put something in the spooler, there's got to be room for it
and if I produce something, I need to decrement that .
so, producer
-----------
down(&empty);
down(&mutex);
.. see handout
read the book
in and out - separate .. mutex currently protects both of them.
.. that slows down the multitasking . we should have two mutexes .. one for ech buffer
.. code is a little more comp;licated but better use of cpu that way
==========(Note Break)==========>>
Tue 02/06/08
producer/consumer handout
prepare a specific example of mutex (for test??)
smeaphores are cool , but they're primative -- unstrctured -- programmers have to think when they use them and have to coordinate
if we so much as switch around producer code
down (mutex);
down(empty):
buff
up(mutex)
up(full)
and leave the consumer code alone
C
down(full)
down(m)
get
up(m)
up(empty))
so if we tarted full =3 empty =0 and mutex =1
it seems silly -- what does it matter -- i protected it -- they key is that I protected the buffer and i did but if we play the game, we see theeerror
suppose P goes first
mutex -> 0
down on empty -- so blocked on empty
so a consumer comes in on next and goes down on full -- full goes from to 2 and then goes doww on mutex
and gets blocked
we already said that any producer will be blocked
consumers can stilll come but then they get put to sleep
so they're all waiting for each other to do an up
deadlock!!
oses need a way of checking on them
or they need useser to say "how come we're not producing anything"
computer scientists have loked at ways of avoiding the use of semaphores
one thing is the idea of a monitor
a _monitor_ is cod generated by a compiler .. so instead of the system programmer doing it, let the compiler do that
so theres specific languages that support a mutex construct
code generated by a comiler that decteds critical regions and signals.
some rules for monitors
rules
1. only one thread or process can be active in the monitor code at a time
that's going to protect the critical region -- put your buffer stuff in the monitor and if only one process can be in there, it's automatically protected .. does ups and downs for you
2. there exists internal monitor signlaing called a condition
if you have a variable type called a condition, you can ask it to wait,
x.wait. === blocks on x
x.signal; wakes up a blocked process on wait
NB: not like semaphores -- like a free get out of jail card ... if there's nobody waiting there .. then the signal's lost .. so you do need to sync that activity
3. after a process issues a signal it must exit the monitor immediately (can't call another function .. because it will violate rule number 1)
if yo're done with tee buffer, get out
handout on page 2
what languages have this construct?
pure c++ does not visual might Java does
public synchronized enter()
{
}
concurrent pascal -- supports these monitors
more examples
another os construct is the message
send(id, data)
receive(id, data)
messigates are good, but there's lots of issues with them
they're really good when you have networking and you're on two different machines
you can get around this by having something called a mailbox
you would send to the mailbox id
and you'd recieve from that mailbox if you had permissions
so htere'd be a neutral place, like a post office that would recieve the mail and hold it until you ask for it
so shared memory again .. but you're not as active with the buffer
mailboxes could fill up
mailboxes are interesting -- they are not used a lot .. they have isssues
how do you know if somethng you sent was recieved
do i block? , acknowledgement?
but what if the ack was lost
when you send a message, where does it go?
do you copy it ot the buffer and then to recieve?
dining philosopher's problem..
reading and writing
writing a file --- you can have integrity issues
you don't want to writers
you don't want readers reading while writers write
so the code on the 2nd last page
answers to questions
job of mutex - protects reader counters so that there's integrity there
c) multiple people need to be able to read -- we only want to protect the rc stuff
d) writing to the database
e) can only write if no-one's reading .. you doon't want every reader doing a down -- just the first one .. and you don't want every reader leaving doing an up -- just the last one.
f) downs in writer code
g) down ups in reader code with rc=1 rc=0
i) it doesn't
j) mutex lets one of them in (protecting counters) the first reader will go down on db because there's a writer writing to db protects that and the other raders that come alonga re going to get blocked on mutex because first reader didn't get a chance to up on mutex
k) readers can starve writers -- if they keep reading, writers can't get anywhere
this is a simple solution
should expect unix to take care of the read and write protection
review sheet on g:
==========(Note Break)==========>>
Thu 02/28/08
don't be a nice guy -- you'll die
handin a printout of the file
and do part A
df = open
form so herman did an open
and david did an open
david is the child .. so herman did an open and forked
theresa did an open an then forked
david has two files open -- david inherits
so theresa should have forked an then opened the file
but herman and dvid are probably not going to use theresa's file
so herman gets a copy of the fdt
so he has theresas connection in his fdt and his connection to the file
what about david?
david will treat the file like herman does in our example .. but david does have the theresa pointer
so it would have been in theresa's best interest to wait on opening the file.
not going to ask what ps means
how to bring something to the foreground -- but you need to know that you can do it
waitpid know name and how to use it
if you describe it , that's fair -- we can look it up otherwise.
fdt - specirfic to a process, but thereads share them .. all references to open files
file system table - files for the while system
iNode
everything that can be, they use the abstraction "file"
so things like pipes, socekts would all be in the fdt
.. stored in the PCB.
for exam -- question on threads and processes know the difference
what makes this all an issue is p-switching.
trapping over
if you were a process, what does the operating system care about you?
you are either running or sleeping or ready and ready isn't really sleeping .. not active but yo're going to be -- you're on call.
sleeping means you can't go on - waiting for I/O..
what to do when waiting for data? well block of course
we can set a few commands to not block
the wait command blocks -- waits for a signal from a child.
pid = wait(&status);
waitpid -- you have an option of setting it to blovvk or not
read, on a file, by default is a blocking read -- if there's nothing htere yet, it waits, but you can set it to no block -- non blocking if nothings there keep going
if you're going to use the informatin right away, thats not handy
how do you set those things? fctrl(
when you open a file, a bunch of arguements you can give for reading and writing .. all inds of options
fctrl works on opened fileds - you might change a file from read to rw
can also change the permissions of the file on the fly
you could change the blocking read to a non-block read and yo'd use fctrl to do that but most of the time we use a blocking read
along with that, how do i/o drive4rs affect miltitasking? - see handouts
driver processor, cpu initiates the driver, processor usually issues an inerrupt when its done so the cpu can do someting different
your network card handles mintue stuff and interrupt when you have something
threads vs processes
what makessthreads so cool? what advantages do they have over processes and why are they not the godnsend .. what are the downsides
semaphores --
idea of a racing condition.
be able to give an example of a racing condiition
take a buffer for example -- suppose that it contains 72 -- now suppose that this hapens and now there's a pswitch and this process does this and this .. don't say airloine reservation and don't explain it
don't worry about the generations of computers
spooling as an example of multitasking - good producer - consumer example
semaphores - lock veriable - what's it fore?
understand the producer consumer code and the reader writer
he'll hold back on monitors and messages
peterson solution - only used two processes -- don't need to know that .. that's memorization
racing condition
lock variable is almost a solution
semaphore
TSL .. test and set lock
don't memorize the code but know what it means
lab on semaphores - know how up works, and how down works
how init works
init(s, value); - starting with a certain value
getdown(s, & value) - returns how many processes are sleeping on that semaphore.
getvalue(s, &value) - tells you the value of a semaphore - helpful on full and empty.
remove(s); - he who created it gets to destroy it
forking with children
fdt - important!
interrupt driven - at the guts of how multitaksing works
don't worry about dma
programmed i/o vs interrupt driven i/o
meet monday at 3.
==========(Note Break)==========>>
Mon 03/03/08
mostly pseudo code .. hardly any code
pseudo code that looks very close
question on fdt!
- code and what doees it do .. one or more files involved
learn the picture
forking isn't i/o -- so you don't necessarily lose the cpu when you fork
you can't make something happen when using an operating system -
if you can draw the picture, that might be helpful in answering the question
I-NOde ---> device
inode has permis;sions, counter of how many processes have issud an open
what you get when you do an ls -l
physical inofrmation about the file
file system table - 1 entry per open
file pointer - push a file pointer along by reading from the file
df = open() //gives you an entry and a couter in the inode =1
fdt - next available entry is 3 = the index of the pointer
that's going to point to the entry in the system file table
so now if we do a fork
the child will have a copy of the fdt - doesn't share it
variables are separate, but the same thing the parent is pointing to
now if the child opens a file, they get a new entry in the fdt, .. leaving the parent's orphaned if you use the same variable name
so if this guy the child does a read from fd, that's coming off of their entry in the system file table
if you want to read off the parent's version -- you can use the number 3
question on threads - difference between a thread and a process .. subtleties
compiler generated threads and OS generated threads .. so a compiler generated thread, the OS doesn't even know about and windows doesn't view it as three different threads
a compiler generated thread
basically uses timers ..
says ok unix is giving p1 a certtain amount of time and then it'll do a pswitch and it'll choose another process ...
well if hhere's a thread in p1 .. there'll be code i there -- a thread manager.
so the manager decides which of the threads should run
each thread is like a while .. forever loop and the manger says .. "i'll give you the cpu and then you"
in vb, if it starts doing something and boggs down, it doesn't automatically switch
so compiler threads are programmer threads
on a p-switch, we leave all three threads and go somewhere else
and the ohter process could have threads and a thread manager as well
suppose p1ta was inchrage of lsstening for someting on the internet
so I wouldn't get any work done if I checked and checked in the main .. so the internet thread does that
thing on i/o -- if unix doesn't know that you're threading and you try to do a read or a writee-- hgecause that's a system call .. and you always trap .. and it'll put to sleep the whole process to lseep because it doesn't know you have threads -- downside!
but if it's a thread based OS, then the scheduler can do a thread switch .. you might not get the cpu next, but at least it's doing dsome round robin
and the cool thing about threads is that it's easy to share the buffere because they're in the same program
the not cool thing about processes is that the buffers have to be in the OS some place ... semaphore has to be looked up in ipcs
know that
cpu
and i/o processor
they both execute code and they're independant of each other
so we're parallel processing
so i/o can execute indepedantly of the main processor
so the i/o processor talks to the hardware and can run it and usually the hardware is extremely slow compared to how fast the main cpu can go
so opportunity to get work done
so if the cpu is executing a process and got to the read statement
the OS has given the cpu to the process
only one process can have the cpu
device driver instructs the i/o controlller to get going .. knows how to talk to the i/o controller
so what happens is the process gets suspended because the cpu now ..
we trap down to the kernal .. because it's a read -- and that's on the picture
the cpu will remember where it' at and start executing the driver ..
driver can wait for this .. cpu can poll and do nothing ..
but usally, the driver starts it and then it takes the cpu away , the driver goes to sleep and we schedule another process
so now the controller is busy getting informationsuppose the controller finishes - usually, an interrupt is used here.. issued by the controller
the cpu stops what it was doing and pick up at the device driver
when interrupts are over, they go back to where they were when they left off
so not a p-switch .. cpu executes it
but the read doesn't have to be a blocking read .. program can go do something else
there'll be question on that
don't misuse a term!
know the terminology
id = wait(&status);
id = waitpid(
there'll be a question on children signaling parents
the other way to signal -- semaphores!
not a whole producer-consumer progrblem -- but an explanation
if you don't thread and you have a button, you can't push another button until the first one is over unless it's threaded
==========(Note Break)==========>>
Wed 03/05/08
pipes .. prelude to sockets .. internet communication
signals .. "software interrupt"
.. sends a blip -- not any information .. just signals
sends a blip to a process
something happened to it sends a specific signal
one of them is sigchild -- when a child terminates
^c has the bash processs send a signal to the process in the foreground that it's supposed to terminate
ctrl z sends a signal from the shell to the process telling it to suspend itself and put it in the background
divide by zero -- sends a signal to the process
the compiler might be looking for that iignal and do something with an if statement .. that's not a good thing to do it would tell you
a pointer goes haywire and tries to point outside tee memory space, the os sees that and sends a signal to the process.
hardware interrupts are generated by processors etc
mouse click etc
so like anything else, we're allowed as users to get involved with signal sending as well
icoll thing about unix .. not proprietary about its function calls .. these days windows does too
kill sends a signal
see handout
there are 32 standard unix signals .. 48 on our version of solaris
14 sigalarm
catch a signal -- write my own handler for that signal
signals are an OS construct .. sent to running processes .. not blocked processes
when a process moves from blocked to running, signal is delivered and acted on immediately
can send a signal from within a process
what can you do with a signal if you're sent one -- well you can do nothing .. the OS has defaults already st up
one of the defaults is to ignore
default actions when sent a signal:
- ignore
- quit
- core dump & quit
that's pretty much it .. pretty bleak
what we can do when sent a signal (except for # 9):
- ignore SIG_IGN
- default SIG_DFL
or you can catch it and execute a function
static struct sigaction act;
a signal can't interrupt itself .. has to finish first
bsd makes this a piece of cake .. but berkley is not unix standard -- so we're going to use the posix standard
kill(-1 .. sends signal to shell, too
trap - change the default shell response for an interrupt
alarm from a prompt will tell you how many seconds remain before you're sent the signal
==========(Note Break)==========>>
Tue 03/11/08
CPU scheduling
properties of processes
---------
two properties .. if we understand how processes operate, we can base the scheduler around that
1. process execution is a cycle of cpu and I/O (running and waiting)
certainly a process starts with cpu -- initiates i/o and then waits
and finally there''s a request to terminate
exit ..
research shows that most processes spend their time waiting for 80% of their life
so if you have a secent cpu, multitasking makes sense
2. durations of cpu burses vary but tend to have a frequency distrubution that's a negative exponential or hyper-exponenial
small cpu burst .. large frequency -- large number of processes have short cpu bursts
... large number of processes have short cpu bursts
and a small number of processes have long cpu
ie, you're not going to find in general in typical processing the cpu is used a short amount of time but often
a few statistic algorithms are all math .. yyou'll be in the cpu a good long time..
but databases, most of that's I/O
scheduling processes
processes sit around a lot waiting for something .. waiting for the OS to say "ok , it's your turn"
when waiting around, we don't think of queue as the cs 220 queue.. here queue means that there's a waiting list and who goes noext ..
shceudler involved with it .. set of processes that are waiting for something and a protocall for who comes next .. not necessarily round robin
queue:
down queue (somaphore)
(dead lock - waiting to be free)
signals
I/O - multimedia card - waiting for the buffer to clear
each I/O device has its own queue
ready queue
monitors
messages (waiting to recieve)
each one has it's own queue as scheduler
3 different types of schedulers for the cpu
long term, medium term, and short term
[ready q] ---> (cpu)
short term ^
.. most processes are only going to be in the cpu for a little bit
equal opportunity for everybody
can come out of the cpu for a couple differnt reasons
.. could come out of the cpu when you're time's up
.. or you coul decide to do a read/write .. waating for device
when i'm done with i/o, youget interrupted andc you get to go back to the ready queue
first come first serve might not be the best way to do it .. little old lady holding up the line
behind that
long term scheduler and batch jobs
short term scheduler is going to happen often .. you want it to happen quickly .. when its invoked .. on a quantom or i/o or sooething whee the stage of the machine changes .. so clock iticks, interrupt, fork, open, read , write , down, up,, kill .. trapped to the os .. perfect tie to say that we could do a p-switch here
short term scheduling happens often .. maybe once every 10 milliseconds
.. time consuming .. gotta be done fast or its not worth it
so if it takes 1 milli second to do a p-switch , 9% of the time, there's p-switch gong on instead of any real work
small timeslice = lost of scheduling, but you seem to be always switching ..
if it's too long, then you have processes waiting
long term scheduler works with batch jobs
batch job is something that the systems operator knows a lot of features about the bbatch job .. % of time it uses printer .. how much cpu it needs, probably know what resources it needs, what HDs it needs
this could be payroll or writing out w-2s
could be talking about transactions at a bank - atms transfer at the end of the day
so the long term scheduler can use the info you know about the job and it can look at the mixture of the ready queue .. percentagge of the cpu that's beig used .. so it can pick a job out of the batch that might be best to do at this point
batch jobs tend to use a lot of memory, so that's another issue
so the algorithm for a long term scheduler would look differently than a short term
how often do they happen? maybe when something leaves the ssytem -- system has throttled down
bringing in new jobs in an interactive environment .... a mess .. oses don't like it
unix does best in an interactive environment .. not built to do batch (will do it, of course)
better at just guessing memory requirements
but how do you schedule that?
you can limit the number of terminals that you can get one with, but interactive can throttle up and usually the user takes care of themselves .. system becomes unresponsive, so you give up
ready queue can get large - in some systems, we monitor that and if it gest too big, we'll swap it out
and that's hwere the medium term scheduler comes it
who to pick to get out of the ready queue and who to pick to get back in
when would the medium term scheduler be invoked?
.. memory is finite ... you can't be ready if you're not in primary memroy
if yo're swappeed out , the whole process is put on hold for awhile
or if the scheduler is thrashing .. too many things to choose from
what's a good time - to do this
not i/o -- where would it go to?
so maybe a safe time would be during a formula .. all the variables get swapped out
so who's a good candidate? it depends .. maybe the little old lady that's taking all the time.
how about the process that's almost done?
but how do you know it's almost done? on a batch you'd now that, but on an interactive, I don't have a clue
how do you measure the effectiveness
throughput -- how many jobs per hour are you processing
cpu utilization - but it can alos be busy doing OS stuff .. not just my process stuff
they measure cpu usage by scheduling null when nothing else would have been sceduled
usually 40-80% usage is good.
too busy means that you usually have a lot of things in memory .. a lot of things waiting in queues
response time -- click on the mouse, you want a response
turn around time and the like -- takes into account cpu time and waiting time
i could buy a faster cpu, but then you've just put off the question
.. nothing you can do to make the cpu faster
so what can you control? how long you sit in a queue.
my code is my code .. given this code, it will always run at the same speed
picking the right scheduler .. depends on the mix -- 2am may loook different than email checking time
==========(Note Break)==========>>
Tue 03/25/08
pipes .. one step away from using socets -- socets can use a network and pipes cant
pipes: inter process communication
(unnamed pipes)
(named pipes - CS 460 2007 kratz)
pipes are a kernal construct so they're not owned by processes but used by them
named pipes are kinda like mailboxes
pipe - parent -==- child
or with two children .. shared
reference: Wang 12.1, 12.3, 12.3
ls -l .. looks a directory and gives me a listing of the files
the output goes to standard out
if instead I pipethat (verical line |) .. wil