computer science 213 © 2006 donald acton 342 layering yet again! application programs operating...

Post on 21-Dec-2015

222 Views

Category:

Documents

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1Computer Science 213© 2006 Donald Acton

Layering Yet Again!Layering Yet Again!

Application programs

Operating system

Hardware

General Layering

Structure

Application

Transport

Network

Link

Network

Layering

Application

Unix I/O

File System

Disk Drive

File System

Layering

2Computer Science 213© 2006 Donald Acton

On to protocolsOn to protocols

• We just finished file systems and explored what happened from the disk to the application

• A layered approach was used to organize things

• We are going to start at the application layer and explore computer protocols

3Computer Science 213© 2006 Donald Acton

Communication Between Processes

Communication Between Processes

• When talking about shells the concept of pipes was introduced

grep "ok:" inputfile | sort | less

• This is really just one process sending data to another. It is a form of Interprocess Communication (IPC).

4Computer Science 213© 2006 Donald Acton

Local IPCLocal IPC

Process1

Process2

Pipe

5Computer Science 213© 2006 Donald Acton

Remote IPCRemote IPC

Process1

Process2

Pipe

6Computer Science 213© 2006 Donald Acton

What Problems Does this Present?

What Problems Does this Present?

Process1

Process2

7Computer Science 213© 2006 Donald Acton

Problem SummaryProblem Summary

• Initiator needs– something to write

to– to identify the

recipient– to define the

“language” of the data exchange

– a mechanism to make the call

• Receiver needs– something to read

from– to define the

“language” of the data exchange

– a mechanism to accept a call

– “caller ID” (sort of)

8Computer Science 213© 2006 Donald Acton

IPC StagesIPC Stages

A communication between processes can be decomposed into 3 stages:

1. Establishing the connection between the callee and caller

2. Transferring of data3. Disconnecting (closing) the connection

The collection of calls involved in the above phases is the Socket API

9Computer Science 213© 2006 Donald Acton

Identifying the CalleeIdentifying the Callee

• Must identify the machine being called– DNS Name (www.cs.ubc.ca) is the human

readable form– Gets translated to an IP address

(142.103.6.5, 127.0.0.1)

• Must identify the recipient on the machine– Port number – Port 80 (www-http), 194 (irc)

10Computer Science 213© 2006 Donald Acton

Internet ConnectionsInternet Connections

Connection socket pair(128.2.194.242 :51213, 208.216.181.15:80)

Receiver(port 80)

Sender

Sender socket address128.2.194.242:51213

Receiver socket address208.216.181.15:80

Sender host address128.2.194.242

Receiver host address208.216.181.15

Adapted from: Computer Systems: A Programmer’s Perspective

11Computer Science 213© 2006 Donald Acton

Establishing the Connection (1)Establishing the Connection (1)

• Caller– Creating the

“endpoint”

int fd;

fd = socket(PF_INET,SOCK_STREAM,0);

12Computer Science 213© 2006 Donald Acton

Establishing the Connection (2)Establishing the Connection (2)

• Caller– Getting ready to make the call

struct sockaddr_in remoteAddr;unsigned long remoteIP = htonl(0xAB112090);

memset(&remoteAddr, 0, sizeof(remoteAddr));remoteAddr.sin_family = PF_INET;memcpy(&remoteAddr.sin_addr.s_addr, &remoteIP, sizeof(remoteIP));remoteAddr.sin_port = htons(7891);

13Computer Science 213© 2006 Donald Acton

Establishing the Connection (3)Establishing the Connection (3)

• Caller– Making the actual call

connect(fd, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr));

• Ready to transmit/receive data when the call returns

14Computer Science 213© 2006 Donald Acton

CalleeCallee

Caller1. Create a socket

2. Connect to

callee3. Transfer data4. Close

connection

Callee1. Create socket2. Specify contact

point (binding)3. Listen for calls4. Accept call5. Transfer data6. Close connection

15Computer Science 213© 2006 Donald Acton

Establishing the Connection (1)Establishing the Connection (1)

Callee – struct sockaddr_in callerAddr; memset(&callerAddr,0,sizeof(callerAddr)); callerAddr.sin_family = PF_INET; callerAddr.sin_addr.s_addr =

htonl(INADDR_ANY);

callerAddr.sin_port = htons(7891); bind(fd, (struct sockaddr *) &callerAddr, sizeof(callerAddr))

16Computer Science 213© 2006 Donald Acton

Purpose of BindPurpose of Bind

• Consider a machine with multiple network cards – Wireless and wired– Server on more than one network

17Computer Science 213© 2006 Donald Acton

Establishing the Connection (2)Establishing the Connection (2)

• Callee – must tell the system it is ready to listen for connectionslisten(fd, 4)– fd – file descriptor of socket to listen– 2nd argument is how many unanswered

calls to queue up (your call is important to us please stay on the line!)

18Computer Science 213© 2006 Donald Acton

Establishing the Connection (3)Establishing the Connection (3)

• Callee needs to actually accept the call

struct sockaddr_in caller;int cl_len = sizeof(caller);int callerFD;callerFD = accept(fd, (struct sockaddr *)&caller, &cl_len);

19Computer Science 213© 2006 Donald Acton

Setting up a ConnectionSetting up a Connection

listenfd(3)

Caller

1. Callee blocks in accept, waiting for connection request on listening descriptor listenfd.

clientfd

Callee

listenfd(3)

Caller

clientfd

Callee 2. Caller makes connection request bycalling and blocking in connect.

listenfd(3)

Caller

clientfd

Callee

3. Callee returns connfd from accept.Caller returns from connect. Connection is now established between clientfd

and connfd.

connectionrequest

connfd(4)

Adapted from: Computer Systems: A Programmer’s Perspective

20Computer Science 213© 2006 Donald Acton

Who Called?Who Called?

• Callee can determine caller by examining 2nd parameter

unsigned long callerIP = ntohl(caller.sin_addr.s_addr);unsigned short = ntohs(caller.sin_port);

21Computer Science 213© 2006 Donald Acton

DisconnectingDisconnecting

• Either caller or callee can terminate a connection with the close() system call

close(callerFD);

22Computer Science 213© 2006 Donald Acton

Exchanging DataExchanging Data

• Once the connection is established caller and callee can both send and receive data– i.e. the connection is bi-directional– The data is not interpreted by the

sockets and it is just a series of bytes. – Calls to send and receive are:

•send()/write()•recv()/read()

23Computer Science 213© 2006 Donald Acton

The CallerThe Caller#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <time.h>int main(){ int fd; fd = socket(PF_INET, SOCK_STREAM,

0);

struct sockaddr_in remoteAddr; unsigned long remoteIP = htonl(0x7F000001); memset(&remoteAddr, 0,

sizeof(remoteAddr));

remoteAddr.sin_family = PF_INET; memcpy(&remoteAddr.sin_addr.s_addr, &remoteIP, sizeof(remoteIP)); remoteAddr.sin_port = htons(7891);

if (connect(fd, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr)) < 0) {

perror("Connection failed"); } else { char *msg = "Hi there\n"; time_t ltime; char buff[256]; time(&ltime); write(fd, &ltime, sizeof(ltime)); write(fd, msg, 10); int amt; amt = read(fd, buff, 256); while( amt > 0) { printf("Buffer %s", buff); amt = read(fd, buff, 256); } }}

24Computer Science 213© 2006 Donald Acton

Caller´ (1)Caller´ (1)

#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <time.h>int main(){ int fd; fd = socket(PF_INET, SOCK_STREAM, 0);

25Computer Science 213© 2006 Donald Acton

Caller´ (2)Caller´ (2)

struct sockaddr_in remoteAddr;

unsigned long remoteIP = htonl(0x7F000001);

memset(&remoteAddr, 0, sizeof(remoteAddr));

26Computer Science 213© 2006 Donald Acton

Caller´ (3)Caller´ (3)

remoteAddr.sin_family = PF_INET;

memcpy(&remoteAddr.sin_addr.s_addr, &remoteIP, sizeof(remoteIP));

remoteAddr.sin_port = htons(7891);

if (connect(fd, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr)) < 0) {

27Computer Science 213© 2006 Donald Acton

Caller´ (4)Caller´ (4)

perror("Connection failed"); } else { char *msg = "Hi there\n"; time_t ltime; char buff[256]; time(&ltime); write(fd, &ltime, sizeof(ltime)); write(fd, msg, 10); int amt;

28Computer Science 213© 2006 Donald Acton

Caller´Caller´

amt = read(fd, buff, 256);

while( amt > 0) {

printf("Buffer %s", buff);

amt = read(fd, buff, 256);

}

}

}

29Computer Science 213© 2006 Donald Acton

CalleeCallee#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <time.h>int main(){ int fd; fd = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in callerAddr; memset(&callerAddr, 0, sizeof(callerAddr)); callerAddr.sin_family = PF_INET; callerAddr.sin_addr.s_addr = htonl(INADDR_ANY); callerAddr.sin_port = htons(7891); bind(fd, (struct sockaddr *) &callerAddr,

sizeof(callerAddr)); listen(fd, 4); struct sockaddr_in caller;

while(1) { int cl_len = sizeof(caller); int callerFD; callerFD = accept(fd,

(struct sockaddr *)&caller, &cl_len);

char buff[256]; int amt; time_t rtime; recv(callerFD, &rtime, sizeof(time_t), 0); amt = recv(callerFD, buff, 256, 0); printf("%s", buff); struct hostent *hp; hp = gethostbyaddr((char *)

&caller.sin_addr.s_addr, sizeof(long), PF_INET);

amt = snprintf(buff,256, "Connection from %s (%x) %x at %s",

hp->h_name, ntohl(caller.sin_addr.s_addr), (long) ntohs(caller.sin_port), ctime(&rtime));

send(callerFD, buff, amt, 0); sleep(10); send(callerFD, "Bye\n", 5, 0); close(callerFD); }}

30Computer Science 213© 2006 Donald Acton

Callee (1)Callee (1)

#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <time.h>int main(){ int fd;

fd = socket(PF_INET, SOCK_STREAM, 0);

31Computer Science 213© 2006 Donald Acton

Callee (2)Callee (2)

struct sockaddr_in callerAddr;

memset(&callerAddr, 0, sizeof(callerAddr));

callerAddr.sin_family = PF_INET;

callerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

callerAddr.sin_port = htons(7891);

32Computer Science 213© 2006 Donald Acton

Callee (3)Callee (3) bind(fd, (struct sockaddr *) &callerAddr, sizeof(callerAddr));

listen(fd, 4);

struct sockaddr_in caller;

while(1) {

int cl_len = sizeof(caller);

int callerFD

callerFD = accept(fd, (struct sockaddr *)&caller, &cl_len);

33Computer Science 213© 2006 Donald Acton

Callee (4)Callee (4)

char buff[256];

int amt;

time_t rtime;

recv(callerFD, &rtime, sizeof(time_t), 0);

amt = recv(callerFD, buff, 256, 0);

printf("%s", buff);

34Computer Science 213© 2006 Donald Acton

Callee (5) Callee (5)

struct hostent *hp; hp = gethostbyaddr((char *) &caller.sin_addr.s_addr, sizeof(long),PF_INET);

amt = snprintf(buff,256, "Connection from %s (%x) %x at %s",

hp->h_name, ntohl(caller.sin_addr.s_addr), (long) ntohs(caller.sin_port), ctime(&rtime));

35Computer Science 213© 2006 Donald Acton

Callee (6)Callee (6)

send(callerFD, buff, amt, 0);

sleep(10);

send(callerFD, "Bye\n", 5,0);

close(callerFD);

}

}

36Computer Science 213© 2006 Donald Acton

Typical Call ProgressTypical Call ProgressCaller Callee

socket socket

bind

listen

accept

close

read

writeread

connect

write

read

Connectionrequest

EOF

Await connectionrequest fromnext caller

Adapted from: Computer Systems: A Programmer’s Perspective

37Computer Science 213© 2006 Donald Acton

BSD Socket API SummaryBSD Socket API Summary• socket() – creates the socket• connect() – initiate a connection• bind() – indicates the IP address to use• listen() – marks the socket to receive

connections• read()/recv() – reads data• write()/send() - writes data• close() – shuts down the connection

38Computer Science 213© 2006 Donald Acton

Other Useful FunctionsOther Useful Functions

• inet_aton() – string to network address

• inet_ntoa() – network address to string

• gethostbyname() gethostbyaddr() given a host name or address look it up

39Computer Science 213© 2006 Donald Acton

Client Server ModelClient Server Model

• When designing a network based application how can we decide what goes where?

• One approach is to divide the functionality into client and server components

40Computer Science 213© 2006 Donald Acton

Client/ServerClient/Server

• Client – is a process that is requesting some sort of service

• Server – is a process that supplies a service

• A particular process can be both a client and server

41Computer Science 213© 2006 Donald Acton

Changing RolesChanging Roles

Database

HTTP Server

42Computer Science 213© 2006 Donald Acton

Request/ResponseRequest/Response

Clientprocess

Serverprocess

1. Client sends request

2. Server processes

request

3. Server sends response4. Client processesresponse

Resource

Adapted from: Computer Systems: A Programmer’s Perspective

43Computer Science 213© 2006 Donald Acton

The Chat ProblemThe Chat Problem

• Consider the following application scenario– Two network connected computers – Want to implement “chat”– When each user types their typing

appears on the other screen– User’s do not have to take turns and can

type at any time

44Computer Science 213© 2006 Donald Acton

The Application’s TaskThe Application’s Task• Each application has two things to do

it must:– Read input from the keyboard and send

it to the remote machine– Read input from the remote machine

and write it to the screen

45Computer Science 213© 2006 Donald Acton

Start with what we knowStart with what we know

• Assume we have the network connection established

while(1) {

read from networkwrite to screenread from keyboardwrite to network

}

46Computer Science 213© 2006 Donald Acton

Do it with Fork!Do it with Fork!

if (fork()) { // parent

read from network

write to screen

} else { //child

read from keyboard

write to network

}

47Computer Science 213© 2006 Donald Acton

Fork()Fork()

Chat ChatSocket

Chat Chat

48Computer Science 213© 2006 Donald Acton

That was easy!That was easy!

• But…..– The overhead of forking the process is

high especially if the child is short lived– Exchanging information between the

child and parent is difficult– It is difficult for the parent to track the

children for resource management issues

49Computer Science 213© 2006 Donald Acton

HTTP Server ExampleHTTP Server Example

• Accepts connections• Client sends commands

– GET, POST, OPTIONS, HEAD, PUT, DELETE

• Commands are in plain text ASCII• Server parses the request and sends

back content• 99% of HTTP requests are GETs

50Computer Science 213© 2006 Donald Acton

Niave HTTP serverNiave HTTP server

while (1) {

accept connection

perform http request

close connection

}

51Computer Science 213© 2006 Donald Acton

Request TimelineRequest Timeline

52Computer Science 213© 2006 Donald Acton

HTTP Server – fork()HTTP Server – fork()while (1) {accept connection

if (fork() == 0) { perform http request processing} else {

if (too many workers) { wait for worker

}}

53Computer Science 213© 2006 Donald Acton

Observations about ServerObservations about Server

• We would like to control the number of processes created

• Each request is computationally light and has little state and is small

• Also, could we have a design that, if appropriate, doesn’t force the client to open a new connection for each request?

54Computer Science 213© 2006 Donald Acton

Worker PoolWorker Pool

• How about a model where there are a bunch of workers

• One worker checks for a connection to see if data arrives

• On data arrival worker services request

• New worker starts waiting

55Computer Science 213© 2006 Donald Acton

Worker Pool DemonstrationWorker Pool Demonstration

56Computer Science 213© 2006 Donald Acton

Process ShortcomingsProcess Shortcomings

• Switching between processes (i.e. scheduling) is slow

• Sharing large amounts of data through pipes or sockets is difficult

57Computer Science 213© 2006 Donald Acton

ThreadsThreads

• To get rid of some of the problems of processes we can use threads

• Threads– Are started by a process and stay within

that process– Execute independently of each other– Share the same memory space

58Computer Science 213© 2006 Donald Acton

Threads and ProcessesThreads and Processes

Computer

59Computer Science 213© 2006 Donald Acton

Thread StatesThread States

New

Ready

Blocked

DeadRunning

60Computer Science 213© 2006 Donald Acton

Thread APIThread API

• Defined by POSIX.1c• The API defines > 60 functions!!!• Java Thread class is much smaller

and many of the methods are informational

61Computer Science 213© 2006 Donald Acton

Most Useful Thread FunctionsMost Useful Thread Functions

• Creating a thread• Starting the thread• Waiting for a thread to terminate• Terminating a thread• To simplify the using of threads let’s

develop an encapsulation of the simplest thread functions

62Computer Science 213© 2006 Donald Acton

Encapsulation StrategyEncapsulation Strategy

Recall that an object is:–A collection of data that captures the state of the object

–A collection of methods that operate on the state

Is there some way to emulate this in a language like C?

63Computer Science 213© 2006 Donald Acton

Approach?Approach?

What C construct could be used to aggregate data?

structsWhat about methods?

functions

64Computer Science 213© 2006 Donald Acton

OrganizationOrganization

Java• new

C• A function that

allocates and initializes the struct and returns a pointer to the struct

struct Point { float x; float y; };

void *newPoint() {

struct Point *pt;

if (pt = malloc(sizeof(struct Point))) {

pt->x = pt->y = 0;

}

return pt;

}

65Computer Science 213© 2006 Donald Acton

Organization cont’dOrganization cont’d

Java• Method invocation

point.method()

C• Just call a function,

but make the first parameter be the “object”

void *pt;

pt = newPoint();

setPoint(pt, 3.4, 1.3);

66Computer Science 213© 2006 Donald Acton

Encapsulation ExampleEncapsulation Example

struct Point { float x; float y; };

void *newPoint() {

struct Point *pt;

if (pt = malloc(sizeof(struct Point))) {

pt->x = pt->y = 0;

}

return pt;

}

void setPoint(void * obj, float x, float y) {

struct Point *pt = obj;

pt->x = x;

pt->y = y;

}

main() {

void *pt;

pt = newPoint();

setPoint(pt, 3.4, 1.3);

….

}

67Computer Science 213© 2006 Donald Acton

Relationship Between Thread Encapsulation and pthread

Relationship Between Thread Encapsulation and pthread

pthread

A

pthread

B

pthread

C

Thread

A

Thread

B

Thread

C

68Computer Science 213© 2006 Donald Acton

Needed FunctionalityNeeded Functionality• Creation

– int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine, void*), void *arg);

• Cancellation – int pthread_cancel( pthread_t target_thread);

69Computer Science 213© 2006 Donald Acton

Functionality cont’dFunctionality cont’d

• Join– int pthread_join(pthread_t thread,

void **status);

• Detach– int pthread_detach( pthread_t thread);

71Computer Science 213© 2006 Donald Acton

Thread StructThread Struct

struct Thread {

void *(*entry_pt)(void*);

void *arg;

pthread_t id; // the thread ID

};int pthread_create(pthread_t *thread,

const pthread_attr_t *attr, void *(*start_routine, void*), void *arg);

72Computer Science 213© 2006 Donald Acton

Thread FunctionsThread Functions

void *createThread(void* (*func)(void*),

void *parm);

int runThread(void *vthread, pthread_attr_t *attr);

int cancelThread(void * vthread);

int joinThread(void * vthread, void **thread_return);

73Computer Science 213© 2006 Donald Acton

Thread Functions cont’dThread Functions cont’d

int detachThread(void *vthread);

pthread_t getThreadID( void *vthread);

void* getThreadArg( void *vthread);

78Computer Science 213© 2006 Donald Acton

createThreadcreateThread

void *createThread(void* (*func)(void*), void * parm) {

struct Thread *thread; thread = malloc(sizeof(struct Thread)); if (thread) { thread->entry_pt = func; thread->arg = parm; } return thread;}

79Computer Science 213© 2006 Donald Acton

runThreadrunThreadint runThread(void *vthread, pthread_attr_t *attr) { struct Thread *thread = vthread; if (vthread) { return pthread_create(&thread->id, attr,

thread->entry_pt, thread->arg ); } return -10;}

int cancelThread(void * vthread){ struct Thread *thread = vthread; return pthread_cancel(thread->id);}

80Computer Science 213© 2006 Donald Acton

joinThreadjoinThreadint joinThread(void * vthread, void **thread_return){ struct Thread *thread = vthread; return pthread_join(thread->id, thread_return);}

int detachThread(void *vthread) // reaps a thread{ struct Thread *thread = vthread; return pthread_detach(thread->id);}

81Computer Science 213© 2006 Donald Acton

AccessorsAccessorspthread_t getThreadID(void *vthread){ struct Thread *thread = vthread; return thread->id;}

void* getThreadArg(void * vthread){ struct Thread *thread = vthread; return thread->arg;}

85Computer Science 213© 2006 Donald Acton

Creating and Running a ThreadCreating and Running a Thread

void *sortAndPrint(void *array) { … }

void *t2;t2 = createThread(sortAndPrint, ar1);runThread(t2, NULL);detachThread(t2); // Only call after

// runcancelThread(t2);free(t2);

86Computer Science 213© 2006 Donald Acton

JoiningJoining

• Threads can only execute as long as their containing process exists

• The main() body of a program is a thread

• If any thread either directly or indirectly calls exit() or _exit() the process will be terminated

87Computer Science 213© 2006 Donald Acton

Joining cont’dJoining cont’d

• If all the process’s work is being done by threads started from main() then main must not return prematurely

• Any thread can wait for another thread with the pthread_join() call encapsulated by:

joinThread(t2, NULL);

88Computer Science 213© 2006 Donald Acton

Example Sorting and Printing

Example Sorting and Printing

• Have a function that takes as an argument an array of integers, sorts, and then prints them

• main() – Creates 3 arrays of integers– Creates 3 threads – Starts all 3 threads “simultaneously”

89Computer Science 213© 2006 Donald Acton

Sort and PrintSort and Printint cs213Compare(const void *a, const void *b) { return *(int *)a - *(int *)b;}

void *sortAndPrint(void *array) { int i; int *b; b = (int *) array; qsort(array, aSize, sizeof(int), cs213Compare); for (i=0; i<aSize; i++) { printf("%3d ", b[i]); fflush(stdout); } printf("\n"); return NULL;}

90Computer Science 213© 2006 Donald Acton

Sort and PrintSort and Print

int main(int argc, char * argv[]){ int array1[aSize]; int array2[aSize]; int array3[aSize]; int i; srandom(time(NULL)); for (i = 0; i < aSize; i++) { array1[i] = random() % (aSize * 10); array2[i] = random() % (aSize * 10); array3[i] = random() % (aSize * 10); printf("%3d %3d %3d\n", array1[i], array2[i],

array3[i]); }

91Computer Science 213© 2006 Donald Acton

Sort and PrintSort and Print printf("\n");

void *t1, *t2, *t3; t1 = createThread(sortAndPrint, array1); t2 = createThread(sortAndPrint, array2); t3 = createThread(sortAndPrint, array3);

runThread(t2, NULL); pthread_attr_t attr; pthread_attr_init(&attr); runThread(t3, &attr); runThread(t1, NULL);

joinThread(t1, NULL); joinThread(t2, NULL); joinThread(t3, NULL); return 0;}

92Computer Science 213© 2006 Donald Acton

Compare FunctionCompare Function

int cs213Compare(const void *a, const void *b) {

return *(int *)a - *(int *)b;

}

93Computer Science 213© 2006 Donald Acton

Sort and Print FunctionSort and Print Function

void *sortAndPrint(void *array) { int i; int *b; b = (int *) array; qsort(array, aSize, sizeof(int), cs213Compare); for (i=0; i<10; i++) { printf("%3d ", b[i]); fflush(stdout); } printf("\n"); }

94Computer Science 213© 2006 Donald Acton

Filling the arraysFilling the arrays

srandom(time(NULL));

for (i = 0; i < aSize; i++) {

array1[i] = random() % (aSize * 10);

array2[i] = random() % (aSize * 10);

array3[i] = random() % (aSize * 10);

printf("%3d %3d %3d\n", array1[i], array2[i], array3[i]);

}

95Computer Science 213© 2006 Donald Acton

Running the ThreadsRunning the Threadsvoid *t1, *t2, *t3;t1 = createThread(sortAndPrint, array1);t2 = createThread(sortAndPrint, array2);t3 = createThread(sortAndPrint, array3);

runThread(t2, NULL);pthread_attr_t attr; pthread_attr_init(&attr);runThread(t3, &attr); runThread(t1, NULL); joinThread(t1, NULL);joinThread(t2, NULL);joinThread(t3, NULL);

96Computer Science 213© 2006 Donald Acton

Output 1Output 1 53 14 27 2 31 85

30 11 67

50 7 39

29 16 79

3 99 90

40 26 32

29 82 64

15 61 73

75 38 23

This is the output from main of the unsorted numbers

97Computer Science 213© 2006 Donald Acton

Output 2Output 2

2 3 15 29 29 30 40 50 53 75 7 11 14 16 26 31 38 61 82 99

23 27 32 39 64 67 73 79 85 90

98Computer Science 213© 2006 Donald Acton

Output 3Output 3

2 3 15 29 7 61 … 53 75 99

23 27 32 39 64 67 73 79 85 90

2 3 15 29 7 … 99 50 53 32 75 39

64 67 73 79 85 90

99Computer Science 213© 2006 Donald Acton

What Happened?What Happened?

• Before one thread finished, its quantum expired and another thread was run

• The thread switched out hadn’t finished

• Exactly when the switch occurs is unpredictable; therefore the output is unpredictable

100Computer Science 213© 2006 Donald Acton

But why?But why?

• What is being shared?– The file descriptor attached to stdout, in

this example it is the screen (window)– Each time the thread is given a time

quantum it writes to stdout– The threads are taking turns writing to

stdout, hence the mixed output

101Computer Science 213© 2006 Donald Acton

Real life examplesReal life examples

• Can you think of some real life examples where there is some notion of sharing, how is it regulated?

102Computer Science 213© 2006 Donald Acton

Semaphores, the Computer Equivalent

Semaphores, the Computer Equivalent

• Developed by Edsger Dijkstra to solve synchronization problem in concurrent programming environments

• A special global variable, s, that can only be manipulated by the operations P(s) (proberen) and V(s) (verhogen)

• Works for both processes and threads

103Computer Science 213© 2006 Donald Acton

AtomicAtomic

Definition: A series of actions is said to be

atomic if the execution of the actions has the exact same result as if the actions had been performed sequentially without interruption.

104Computer Science 213© 2006 Donald Acton

Semaphore SemanticsSemaphore Semantics

• V(s) [ s = s + 1]– Operation is performed atomically

• P(s) [while (s == 0) {wait}; s = s – 1]– The test for 0 and decrement are done

atomically– If s is 0 then the process waits until the

value of s is modified by a V operation

105Computer Science 213© 2006 Donald Acton

Underlying Semaphore Implementation

Underlying Semaphore Implementation

We know– That an application can be interrupted

at any time– That the kernel can schedule a new

process to run– When executing in the kernel interrupts

are disabled therefore any series of instructions is atomic

106Computer Science 213© 2006 Donald Acton

Semaphore APISemaphore API

• Part of POSIX 1003.1b• Supplies semaphores in various

formats• Upon creation the semaphore values

is normally set to 0, although other values are allowed

• You will work with the supplied Semaphore class

107Computer Science 213© 2006 Donald Acton

Semaphore EncapsulationSemaphore Encapsulation

void P(sem_t *_sysSem);

void V(sem_t *_sysSem);

sem_t createSemaphore();void destroySemaphore(sem_t

**_sysSem);

108Computer Science 213© 2006 Donald Acton

createSemaphore()createSemaphore()

sem_t *createSemaphore(int count) { sem_t *_sysSem = malloc(sizeof(sem_t)); if (_sysSem) { memset( _sysSem, 0, sizeof( sem_t ) ); if (sem_init(_sysSem, 0, count) != 0) { // perror("Getting semaphore failed"); free(_sysSem); _sysSem = NULL; } } return _sysSem;}

109Computer Science 213© 2006 Donald Acton

destroySemaphore()destroySemaphore()

void destroySemaphore(sem_t **_sysSem ) { if (_sysSem && *_sysSem) { if (sem_destroy(*_sysSem) != 0) { perror("Semaphore Destr. failed"); } else { free(*_sysSem); *_sysSem = NULL;

}}

}

110Computer Science 213© 2006 Donald Acton

P()P()

void P(sem_t * _sysSem) { // wait, lock if (sem_wait(_sysSem) != 0) {

perror("Semaphore P() blocking");

pthread_cancel(pthread_self());

for(;;) sleep(60000);

} }

111Computer Science 213© 2006 Donald Acton

V()V()

void V(sem_t *_sysSem) { //signal, unlock

if (sem_post(_sysSem) != 0) {

perror("Sem V()blocking");

pthread_cancel(pthread_self());

for(;;) sleep(60000);

}

}

112Computer Science 213© 2006 Donald Acton

V()P()

V()

Semaphores in ActionSemaphores in Action

P()

P() V()T1

T2

T3

Time

113Computer Science 213© 2006 Donald Acton

Using P() and V() in Sort and Print ExampleUsing P() and V() in

Sort and Print Example• All threads must use the same

semaphore • Given the way we have put things

together a global variable for the semaphore will be needed

• Add code sem_t *s = createSemaphore(1);

before the definition of sortAndPrint()

114Computer Science 213© 2006 Donald Acton

Where do P() and V() go?Where do P() and V() go?

void *sortAndPrint(void *array) { int i; int *b; b = (int *) array; qsort(array, aSize, sizeof(int), cs213Compare); for (i=0; i<10; i++) { printf("%3d ", b[i]); fflush(stdout); } printf("\n"); }

115Computer Science 213© 2006 Donald Acton

Semaphores & BanksSemaphores & Banks

•Consider a banking system that has a method to transfer money from one account to another

•Uses semaphores to prevent multiple simultaneous transfers from updating the same account at once

116Computer Science 213© 2006 Donald Acton

Solution 1Solution 1

void transfer(int amt, BankA *a1, BankA *a2){

P(s);

if (valid balance) {

Withdraw(a1, amt);

Deposit(a2, amt);

}

V(s);

}

117Computer Science 213© 2006 Donald Acton

Problem with Solution 1Problem with Solution 1

• Withdraw and deposit methods could take a long time if they involve going to disk

• With a single global semaphore no other transfers can be done while waiting, even if the transfer involves completely different accounts

118Computer Science 213© 2006 Donald Acton

Solution 2Solution 2

void transfer(int amt, BankA *a1, BankA *a2){

P(a1->s); P(a2->s); if (valid balance) {

Withdraw(a1, amt);Deposit(a2, amt);

}V(a2->s); V(a1->s);

}

119Computer Science 213© 2006 Donald Acton

Does solution 2 work?Does solution 2 work?

transfer(100,a1,a2);

1. P(a1->s);

2. P(a2->s);

transfer(100,a2,a1);

1. P(a2->s);

2. P(a1->s);

At this point each thread/process is waiting for the other so no further progress, by either thread/process, can be made.

120Computer Science 213© 2006 Donald Acton

DeadlockDeadlock

Definition:A deadlock occurs when two or more processes/threads cannot make computational progress because the processes/threads, either directly or indirectly, are waiting for a resource the other process/thread holds.

121Computer Science 213© 2006 Donald Acton

Wait-for-graphWait-for-graph

– For each process draw a square– For each resource (semaphore) draw a circle– If a resource is held by a process draw an

arrow from the resource to the process – If a process is waiting for a resource draw

an arrow from the process to the resource

If a cycle exists then there is a deadlock in the system

122Computer Science 213© 2006 Donald Acton

Bank – wait-for-graphBank – wait-for-graph

123Computer Science 213© 2006 Donald Acton

Bank – wait-for-graphBank – wait-for-graph

T1 T2

a1.s

a2.s

124Computer Science 213© 2006 Donald Acton

Deadlock DetectionDeadlock Detection

• Can be done by keeping wait-for-graph

• Keeping a wait-for-graph is expensive as each time a resource is acquired, released, or waited for, the graph must be updated

• Running the cycle detection algorithm can consume many resources if it is done too frequently

125Computer Science 213© 2006 Donald Acton

So you found a deadlock, what should be done?

So you found a deadlock, what should be done?

• Something must be done otherwise the system will remain blocked

• Select one of the blocked process and return acquisition call failure

• Which process should be selected– Oldest?– One involved in the most cycles?– One involved in the least cycles?

126Computer Science 213© 2006 Donald Acton

Other StrategiesOther Strategies

• Have a timeout associated with resource acquisition– Don’t have to do deadlock detection– May timeout when there isn’t a deadlock

• Put the onus on the designer to develop deadlock free algorithms

127Computer Science 213© 2006 Donald Acton

Bank -> Deadlock FreeBank -> Deadlock Free

• All process agree to acquire resources in a specific order

128Computer Science 213© 2006 Donald Acton

LivelockLivelock

• More difficult to deal with than deadlock

• Occurs when 2 or more processes change their state in response to each other

• State change has the appearance of doing work (unlike a deadlock) but no computational progress is being made

129Computer Science 213© 2006 Donald Acton

Okay, where were we?Okay, where were we?

• Started this section out with http server

• Wanted threads to replace fork()• Can’t have an unlimited number of

threads so use a worker pool• Need semaphores to help with the

problem of sharing

130Computer Science 213© 2006 Donald Acton

HTTP Server Again!HTTP Server Again!

while (1) {accept connection

if (fork() == 0) { perform http request processing} else {

if (too many workers) { wait for worker

}}

131Computer Science 213© 2006 Donald Acton

Thread Design ModelThread Design Model

Master

threadBuffer

...

Accept

connections

Insert Request

descriptor Remove

Request

Worker

thread

Worker

thread

Client

Client

...

Service client

Service client

Pool of worker threads

Adapted from: Computer Systems: A Programmer’s Perspective

Server Machine

132Computer Science 213© 2006 Donald Acton

HTTP Server MainHTTP Server Main

main() {setup Socket to listen oninitialize semaphoresstart pool of workerswhile (1) {

accept new connectionprepare requestput request in queue

}

133Computer Science 213© 2006 Donald Acton

Worker ThreadWorker Thread

void *worker(void *data)

{

while (1) {

remove request from queue

service request

close connection

}

134Computer Science 213© 2006 Donald Acton

Queue Access RulesQueue Access Rules

Observations:– There is a single queue of requests

accessed by both the workers and main thread

– Queue has a maximum size– Main thread can only add to queue if

there is room– Worker threads can only remove

something from the queue if something is there

135Computer Science 213© 2006 Donald Acton

ProblemsProblems

• How does the main thread know if the queue is full?

• How do worker threads know if there is work to do?

136Computer Science 213© 2006 Donald Acton

Try 1: A Single SemaphoreTry 1: A Single Semaphore

• Suppose you had a single semaphore, could one determine if there was work to do?

137Computer Science 213© 2006 Donald Acton

Semaphore TricksSemaphore Tricks

• The process/thread that does a P() doesn’t have to be the one to do the V()

• Multiple V()’s can be done to increase the semaphore count – This produces a counting semaphore

and can be used when there are multiple units of a resource

138Computer Science 213© 2006 Donald Acton

Try 2 SemaphoresTry 2 Semaphores

Main ThreadP(nonempty);

Start worker(s)

while (1) {

P(empty);

add req

V(nonempty);

}

Worker Thread

while (1) {

P(nonempty);

remove req

V(empty);

}

139Computer Science 213© 2006 Donald Acton

More Workers and the Queue

More Workers and the Queue

• Works if there can be only 1 request• If we allowed N requests should we

have 1 semaphore per request/queue slot?

140Computer Science 213© 2006 Donald Acton

Try 3 SemaphoresTry 3 Semaphores1. queue – semaphore

• Used to control the shared queue access

2. nonempty – counting semaphore• Initially 0• and indicates non-empty slots

3. empty – counting semaphore• Indicates empty slots initially N• Acquired by main() for each item

added

141Computer Science 213© 2006 Donald Acton

Maintaining the QueueMaintaining the Queue

Main Threadwhile (1) {

P(empty);

P(queue);

add req

V(queue);

V(nonempty)

}

Worker Threadwhile (1){

P(nonempty);

P(queue);

remove req

V(queue);

V(empty);

}

142Computer Science 213© 2006 Donald Acton

The Missing MethodsThe Missing Methods

• Status of a thread running or dead• Setting attributes

– Permitted memory usage– Scheduling policy

• Thread specific data• Concurrency control

– Mutexes– Condition variables– Reader/writer locking

143Computer Science 213© 2006 Donald Acton

When to use fork()When to use fork()

• The task to be performed is logically separate from the “parent’s”

• Protection needed between children• e.g. command execution for a shell

– Shell doesn’t know how long command will take

– Commands are logically separate from the shell

144Computer Science 213© 2006 Donald Acton

When to use threadsWhen to use threads

• The range of actions to be performed is small

• There needs to be information sharing between the “parent” and “child” or between children

top related