+ All Categories
Home > Documents > Processes and Threads

Processes and Threads

Date post: 02-Feb-2016
Category:
Upload: lorne
View: 37 times
Download: 0 times
Share this document with a friend
Description:
CSCI 156. Processes and Threads. Project 2 Server. How would you write it? Multiple connections on multiple ports Communication between input handlers and output generators Some Options Multiple processes Multiple threads One monolithic program. Multiple Processes. pid_t fork(); - PowerPoint PPT Presentation
Popular Tags:
21
Processes and Threads CSCI 156
Transcript
Page 1: Processes and Threads

Processes and Threads

CSCI 156

Page 2: Processes and Threads

Project 2 Server

• How would you write it?– Multiple connections on multiple ports– Communication between input handlers and

output generators

• Some Options– Multiple processes– Multiple threads– One monolithic program

Page 3: Processes and Threads

Multiple Processespid_t fork();

Child process has value of 0 for the returned pidParent has process id of the child

int pid = fork(); if(pid) { printf("I'm the parent! pid=%d\n", pid); } else { printf("I'm just a baby! pid=%d\n", pid); }

This is frequently used to open a new program with exec:fork then have the child exec.

Page 4: Processes and Threads

Multiple Processes (cont.)int execve(const char *filename, char *const argv [], char *const envp[]);

execve() runs the program at path “filename”, with arguments argv and optional environment variables in envp. argv[0] must be the same as filename.

pid_t wait(int *status);

wait() blocks until a child process exits. It then returns the child pid, and fills the status variable with the exit return code of the child.

pid_t waitpid(pid_t pid, int *status, int options);

waitpid() lets you specify a child pid to wait for, and also allows options to be passed

Page 5: Processes and Threads

Multiple Processes (cont.) int pid, status, error; char *name[2], *foo; foo = (char*) malloc(20 * sizeof(char)); printf("give us a string!\n"); scanf("%s", foo);

pid = fork(); if(pid) { printf("I'm the parent! pid=%d\n", pid); if(waitpid(pid, &status, 0) == pid) { printf("my baby died!\n"); } } else { printf("I'm just a baby! pid=%d\n", pid); name[0] = "/bin/echo"; name[1] = foo; execve(name[0], name, NULL); }

Any problems with this code?

Page 6: Processes and Threads

Command Line Argumentsint main (int argc, char* argv[])

{

}

argv - is an array of character pointers to the words that were on the command line

argc - holds the number of words specified in the command (length of argv array)

./myPrg 5

results in argc=2 with argv[0]=“./myPrg” and argv[1]=“5”

int x;

x = atoi(argv[1]); /* Now x=5 */

Page 7: Processes and Threads

Multiple Processes (cont.)int main (int argc, char* argv[]){ int pid, status, error; char *name[2];

pid = fork(); if(pid) { printf("I'm the parent! pid=%d\n", pid); if(waitpid(pid, &status, 0) == pid) { printf("my baby died!\n"); } } else { printf("I'm just a baby! pid=%d\n", pid); name[0] = "/bin/echo"; name[1] = argv[1]; execve(name[0], name, NULL); }}

Page 8: Processes and Threads

Multiple Processes (cont.)forkbomb (n) – 'explodes' by recursively spawning copies of itself. eventually overloads the number of available processes, and stalls the machine.

DO NOT try this on hobbes: Sheryl will destroy you.

main() {for(;;)fork();}

expanded:

int main(){

while(1)fork();

}

Page 9: Processes and Threads

Multiple Processes (cont.)Back to the server: we fork once for each new connection and have the children handle the incoming messages:

create sockets, bind to both portsloop forever

if(incoming sender connection)fork if(child – sender process)

loop waiting for messages on connected socketif a msg/file, send to all recver processes

doneif(incoming recver connection)

forkif(child – recver process)

loop waiting for messages from sender processesif a valid msg/file, send to connected socket

donedone

Page 10: Processes and Threads

Multiple Processes (cont.)Problem with multiple processes is use of Unix IPC methods to communicate between processes:

SIGNALS: sigaction() sets a function to be called when the program gets a signal. kill(pid, signal) sends the signal to a process. Can't send actual data, just two instructions: SIGUSR1 and SIGUSER2

SHARED MEMORY: shmget() is used to create/get a reference to shared memory, then shmat is used to get a normal pointer to it (shmdt to give it up). Use a mutex to control access.

PIPES: pipe() creates two file descriptors that can be used with write/read (like send/recv on sockets). Should be used one-way, created before forking

FIFO (named pipes): special file on disk, created with mkfifo. Uses write/read, but can be used between non-forked programs

Lots more! http://www.ecst.csuchico.edu/~beej/guide/ipc/

Page 11: Processes and Threads

One Monolithic ProgramMust keep an array of open sockets, and when a connection is accept()-ed, add to the list, then have one large loop that checks for incoming information on each open socket, then checks for new connections. Overall structure:

create sockets, bind to both portsloop forever

loop through open sender socketscheck for messages on open “sender” connectionsif(incoming message)

if a msg/fileloop on all open “recver” connections

send message to recverwhile(there are incoming sender connections)

add to sender socket arraywhile(there are incoming recver connections)

add to recver socket arraydone

Advantages/Disadvantages?

Page 12: Processes and Threads

ThreadsThreads are similar to processes, but all run under a single process ID, and share more information than forked processes (exam T/F question?)

Threads have some advantages:

1) less overhead (creating a process = expensive)2) can take more advantage of SMP support3) no need to use Unix IPC: can use mutex locks

But also disadvantages:

1) debugging them can be a pain (better with gdb 6+, kernel 2.6+, but still no fun at all)

2) code is complicated: for simple programs, maybe easier to fork

Page 13: Processes and Threads

Let’s create a thread… How?Need to include the library

#include <pthread.h>

And compile with the -lpthread flag:

gcc -lpthread mySource.c

Like any other type: need to declare and malloc

pthread_t *ghostThread;ghostThread = (pthread_t*)malloc(sizeof(pthread_t));

Page 14: Processes and Threads

Let’s create a thread (cont.)We can then set up the thread and actually start it running:void *our_function (void *parameter) { printf(“Hello World\n”);}

int main () { void* parameter=NULL; pthread_t* pacmanThread; pacmanThread = (pthread_t*)malloc(sizeof(pthread_t));

pthread_create(pacmanThread, NULL, our_function, parameter);

}

Page 15: Processes and Threads

Let’s create a thread (cont.)int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*),

void *arg);  

The pthread_create() function is used to create a new thread, with attributes specified by attr, within a process. If attr is NULL, the default attributes are used. If the attributes specified by attr are modified later, the thread's attributes are not affected. Upon successful completion, pthread_create() stores the ID of the created thread in the location referenced by thread. The thread is created executing start_routine with arg as its sole argument. If the start_routine returns, the effect is as if there was an implicit call to pthread_exit() using the return value of start_routine as the exit status.

Page 16: Processes and Threads

Thread Attribute TypeUsed to pass desired attributes to create

Declaration:pthread_attr_t pthread_custom_attr;

Functions used with:

pthread_attr_init(&pthread_custom_attr);

int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);

Use with policy constants: SCHED_FIFO, SCHED_RR and SCHED_OTHER

int pthread_attr_setstacksize (pthread_attr_t *attr,

size_t stacksize);

Page 17: Processes and Threads

Lets create a thread continuedWe can then set up the thread using the attributes and

actually start it running:

pthread_create(ghostThread, pthread_custom_attr, our_thread_function, parameter);

Page 18: Processes and Threads

Some useful pthread functionsvoid pthread_exit(void *value_ptr);

Called inside our threaded function. The pthread_exit function terminates the thread that calls it and makes the value value_ptr available to its parent (if the parent has joined on it)

int pthread_join(pthread_t thread, void **value_ptr);

The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated. On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() by the terminating thread is made available in the location referenced by value_ptr.

Page 19: Processes and Threads

Locks Declaration:

/* Global Variables */int myInt;pthread_mutex_t myIntLock;

Must be Initialized prior to use:pthread_mutex_init(&myIntLock, NULL);

Locks also have an attribute field (much like threads):

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

Page 20: Processes and Threads

Locking and Unlockingint pthread_mutex_lock(pthread_mutex_t *mutex);

Blocks if someone else has the lock..

int pthread_mutex_trylock (pthread_mutex_t *mutex);

Doesn’t block if someone else has lock. Call returns with failure. Lets you do other things…

Finished with the lock- let it go:

int pthread_mutex_unlock (pthread_mutex_t *mutex);

Page 21: Processes and Threads

Locks FinaleWhen all threads finished with the lock:int pthread_mutex_destroy (pthread_mutex_t *mutex);

pthread_mutex_destroy(&myIntLock);

Spin Waiting – Not preferred way to go. Why?while(!pthread_mutex_trylock(&myIntLock)) {

/* Do nothing */

}

/* critical section */


Recommended