Download presentation
Presentation is loading. Please wait.
1
fork Fork is used to create a child process. Most network servers under Unix are written this way Concurrent server: parent accepts the connection, forks a child, and child handles the client While this paradigm has served well for many years, there are problems with fork:
2
Problem with fork Fork is expensive. Memory is copied from the parent to the child, all descriptors are duplicated in the child, and so on. Interprocess communication(IPC) is required to pass information between the parent and child after the fork. Information from the parent to the child before the fork is easy, since the child starts with a copy of the parent’s data space and with a copy of all the parent’s descriptors. But returning information from the child to the parent takes more work
3
threads Threads are sometime called lightweight process Thread creation can be 10-100 times faster than process creation. All threads within a process share the same global memory. This makes the sharing of information easy between the threads, but along with this simplicity comes the problem of synchronization.
4
All threads within a process share Process instructions Most data Open files( e.g. descriptor) Signal handlers and signal dispositions Current working directory, and User and group IDs
5
Each thread has its own Thread ID Set of registers, including program counter and stack pointer Stack( for local variables and return address) Errno Signal mask and priority
6
Posix thread Posix thread also called Pthreads. Standarized in 1995 and most version of Unix will support them in the future. All thread function begin with pthread_ We will cover five basic thread functions and use these to code TCP client-server using thread instead of fork
7
pthread_create When a program is started by exec, a single thread is created, called the initial thread or main thread. Additional threads are created by pthread_create #include int pthread_create( int *tid, const pthread_attr_t *attr, void*(*func)(void *), void *arg); Return 0 if OK, positive Exxx value on error
8
int pthread_create( int *tid, const pthread_attr_t *attr, void*(*func)(void *), void *arg); Each thread is identified by a thread ID (tid) Each thread has attributes: –Priority, initial stack size and so on. When create a thread, they can be specified or default if pass a null pointer Specify a function to execute. The thread starts by calling function, terminates either explicitly( calling pthread_exit) or implicitly( letting function return). The address of the function Function takes one argument, a generic pointer(void *) and return a generic pointer (void *). This lets us pass one poniter(to anything we want) to the thread, and lets the thread return one pointer( to anything we want)
9
pthread_join function We can wait for a given thread to terminate by calling pthread_join. #include int pthread_join( int tid, void **status); return: 0 if OK, positive Exxx value on error -1 means wait for the first thread to terminate If the status pointer is nonnull, the return value from the thread( a pointer to some object) is stored in the location pointed to by status
10
pthread_self function Each thread has an ID that identifies it within a given process. A thread fetch this value for iteself using pthread_self #include int pthread_self(void); return thread ID of calling thead
11
pthread_detach A thread is either joinable( the default) or detached. When a joinable thread terminates, its thread ID and exit status retained until another thread call pthread_join. When a detached thread terminates, all its resources are released and we cannot wait for it to terminate. If one thread need to know when another thread terminates, it is best to leave the thread as joinable int pthread_detach(int tid); Return 0 if OK, positive Exxx value on error
12
pthread_exit function One way for a thread to terminate is to call pthread_exit. void pthread_exit(void *status); It the thread is not detached, its tid and exit status are retained for a later pthread_join by someother thread in the calling process. The pointer status must not point to an object that is local to the calling thread, since that object disappears when the thread terminates
13
Two other ways for a thread to terminate The function that started the thread( the third argument to pthread_create) can return. Since this function must be declared as returning a void pointer, that return value is the exit status of the thread If the main function of the process returns or if any thread calls exit, the process terminates, including any thread.
14
TCP echo server using thread static void *doit(void *); int main( int argc, char **argv) { int s, conn, tid; for(;;) { len = addrlen; conn = Accept(s, client, &len); pthread_create(&tid, NULL, &doit, (void *)conn); }
15
Doit() static void * doit( void *arg) // arg is conn { pthread_detach(pthread_self()); str_echo((int) arg); close((int)arg); return NULL; }
16
For(;;) { len = addrlen; iptr = malloc(sizeof(int)); *iptr = Accept( s, clinet, &len); pthread_create(&tid, NULL, &doit, iptr); }
17
Doit static void * doit( void *arg) { int conn; conn = *((int *)arg); free(arg); pthread_detach(pthread_self()); string_echo(conn); close(conn); retun (NULL); }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.