800 likes | 820 Views
Multithread API’s. Adam Piotrowski Grzegorz Jabłoński. Lecture I II. Agenda. Signals – software asynchronous interrupts Processes Threads. Signals. Signals are software interrupts that provide a mechanism for handling asynchronous events. The kernel can perform one of three actions:
E N D
Multithread API’s Adam Piotrowski Grzegorz Jabłoński Lecture III
Agenda Signals – software asynchronous interrupts Processes Threads
Signals • Signals are software interrupts that provide a mechanism for handling asynchronous events. • The kernel can perform one of three actions: • ignore • catch and handle • perform default action
Signal handling NAME signal - simplified software signalfacilities SYNOPSIS #include <signal.h> void (*signal(intsig, void*func)(int)))(int); typedefvoid (*sig_t) (int); sig_tsignal(intsig, sig_tfunc);
Signals - Example staticvoidsigint_handler (intsigno) { printf ("Caught SIGINT!\n"); exit (EXIT_SUCCESS); } int main (void) { if (signal (SIGINT, sigint_handler) == SIG_ERR) { fprintf (stderr, "Cannot handle SIGINT!\n"); exit (EXIT_FAILURE); } for (;;) pause ( ); return 0; }
Processes Processes are object code in execution: active, alive, runningprograms. Processes consist of data,resources, state, and a virtualized computer.
Multi processes application parent process fork fork fork fork child process child process child process child process
fork NAME fork -- create a new process SYNOPSIS #include <sys/types.h> #include <unistd.h> pid_tfork(void);
fork example pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { printf(” Parent process”); } else if (pid == 0){ printf(”Child process”); } • variables are duplicated • descriptors are duplicated, too
fork example pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { printf(” Parent process”); } else if (pid == 0){ printf(”Child process”); } pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { printf(” Parent process”); } else if (pid == 0){ printf(”Child process”); }
fork example int sock; while (1){ /* wait for connection from client estabilish communication with client sock = … */ pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { close(sock); } else if (pid == 0){ /*perform data exchange based on sock descriptor*/ close(sock); return 0; } }
processes & SIGCHLD signal int sock; while (1){ /* wait for connection from client estabilish communication with client sock = … */ pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { close(sock); } else if (pid == 0){ /*perform data exchange based on sock descriptor*/ close(sock); return 0; } }
processes & SIGCHLD signal int sock; if (signal (SIGCHLD, sigint_handler) == SIG_ERR) ASSERT(false); while (1){ /* wait for connection from client estabilish communication with client sock = … */ pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { close(sock); } else if (pid == 0){ /*perform data exchange based on sock descriptor*/ close(sock); return 0; } }
processes & SIGCHLD signal staticvoid sigint_handler (int signo) { int status; wait(&status); } int sock; if (signal (SIGCHLD, sigint_handler) == SIG_ERR) ASSERT(false); while (1){ /* wait for connection from client estabilish communication with client sock = … */ pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { close(sock); } else if (pid == 0){ /*perform data exchange based on sock descriptor*/ close(sock); return 0; } }
processes & SIGCHLD signal staticvoid sigint_handler (int signo) { int status; while (waitpid(-1, &status, WNOHANG) > 0); } int sock; if (signal (SIGCHLD, sigint_handler) == SIG_ERR) ASSERT(false); while (1){ /* wait for connection from client estabilish communication with client sock = … */ pid_t pid; pid = fork(); if (pid < 0) ASSERT(false) else if (pid > 0) { close(sock); } else if (pid == 0){ /*perform data exchange based on sock descriptor*/ close(sock); return 0; } }
IPC shared memory signals pipes named pipes message queues sockets semaphores files
Thread vs Processes process complex interprocesses communications (latency, security problem) simple to create and manage more expensive (clear cache) need more memory need more time to switch context Art of Multiprocessor Programming
Thread vs Processes thread process complex interprocesses communications (latency, security problem) simple to create and manage more expensive (clear cache) need more memory need more time to switch context • simple interthread communication • require synchronisation • less expensive • faster to create Art of Multiprocessor Programming
Pthread API thread management thread atributess synchronisation
Creating thread NAME pthread_create - creates a new thread, with attributes specified by attr SYNOPSIS #include <pthread.h> int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void*(*start_routine)(void*), void *arg);
pthread_create example void*thread_fun(void*arg) { if ((int)arg == 7) //do something } pthread_ttid; pthread_attr_tattr; //attrinitialisation ... if (pthread_create(&tid, &attr, thread_fun, (void*)7) ASSERT(false);
Exiting thread NAME pthread_exit - terminates the calling thread, returning status SYNOPSIS #include <pthread.h> void pthread_exit(void *status);
Additional functions NAME thread_self - returns the thread ID of the callingthread. SYNOPSIS #include <pthread.h> pthread_tpthread_self(void); NAME pthread_equal - compares the thread IDs t1 and t2 and returns a non-zero value ifthey are equal; otherwise, it returns zero. SYNOPSIS #include <pthread.h> intpthread_equal(pthread_t t1, pthread_t t2);
Joining threads void *thread_fun(void *arg) { //do something pthread_exit(NULL); } intmain() { pthread_ttid; void* status; if (pthread_create(&tid, NULL, thread_fun, NULL) ASSERT(false); //do something return 0; }
Joining threads void *thread_fun(void *arg) { //do something pthread_exit(NULL); } intmain() { pthread_ttid; void* status; if (pthread_create(&tid, NULL, thread_fun, NULL) ASSERT(false); //do something if (pthread_join(main_thr, &status)) ASSERT(false); return 0; }
Joining threads NAME pthread_join - blocks the calling thread until thread terminates. If status is not null,the status from pthread_exit() will be placed there. SYNOPSIS #include <pthread.h> int pthread_join(pthread_tthread, void **status);
intmain() { pthread_ttid; void* status; if (pthread_create(&tid, NULL, thread_fun, NULL) ASSERT(false); //do something if (pthread_join(main_thr, &status)) ASSERT(false); return 0; } Joining threads void *thread_fun(void *arg) { //do something pthread_exit(NULL); }
What, if we don’t want to wait for thread pthread_attr_tattr; if (pthread_attr_init(&attr)) ASSERT(false); if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) ASSERT(false); /*createnewthread*/ if (pthread_attr_destroy(&attr)) ASSERT(false);
What, if we don’t want to wait for thread NAME pthread_detach- turns the current thread into a detached thread. SYNOPSIS #include <pthread.h> intpthread_detach(pthread_tthread);
Threads attributes All threads attributes are set in a thread attributes object by a function of the form: int pthread_attr_setname( pthread_attr_t *attr, Type t); All threads attributes are retrieved from a threads attributes object by a function of the form: int pthread_attr_getname( pthread_attr_t *attr, Type t);
Threads attributes intpthread_attr_setdetachstate(pthread_attr_t*attr, intdetachstate); intpthread_attr_getdetachstate(constpthread_attr_t *attr, int *detachstate); All threads attributes are set in a thread attributes object by a function of the form: intpthread_attr_setname( pthread_attr_t *attr, Type t); All threads attributes are retrieved from a threads attributes object by a function of the form: intpthread_attr_getname( pthread_attr_t *attr, Type t);
Threads attributes The stacksize attribute shall define the minimum stack size (in bytes) allocated for the created threads stack.
Threads attributes The stackaddr attribute specifies the location of storage to be used for the created thread's stack.
Threads attributes The guardsize attribute controls the size of the guard area for the created thread's stack. The guardsize attribute provides protection against overflow of the stack pointer. If a thread's stack is created with guard protection, the implementation allocates extra memory at the overflow end of the stack as a buffer against stack overflow of the stack pointer.
Threads attributes Control whether the thread is created in the joinable state (PTHREAD_CREATE_JOINABLE) or in the detached state ( PTHREAD_CREATE_DETACHED).
Threads attributes The contentionscope attribute may have the values PTHREAD_SCOPE_SYSTEM, signifying system scheduling contention scope, or PTHREAD_SCOPE_PROCESS, signifying process scheduling contention scope.
Threads attributes • When the attributes objects are used by pthread_create(), the inheritsched attribute determines how the other scheduling attributes of the created thread shall be set. • PTHREAD_INHERIT_SCHED Specifies that the thread scheduling attributes shall be inherited from the creating thread, and the scheduling attributes in this attr argument shall be ignored. • PTHREAD_EXPLICIT_SCHED Specifies that the thread scheduling attributes shall be set to the corresponding values from this attributes object.
Threads attributes The supported values of policy shall include SCHED_FIFO, SCHED_RR, and SCHED_OTHER,
Threads attributes For the SCHED_FIFO and SCHED_RR policies, the only required member of param is sched_priority. For the SCHED_SPORADIC policy, the required members of the param structure are sched_priority, sched_ss_low_priority, sched_ss_repl_period, sched_ss_init_budget, and sched_ss_max_repl. The specified sched_ss_repl_period must be greater than or equal to the specified sched_ss_init_budget for the function to succeed; if it is not, then the function shall fail. The value of sched_ss_max_repl shall be within the inclusive range [1, {SS_REPL_MAX}] for the function to succeed; if not, the function shall fail.
Threads attributes intpthread_setschedparam(pthread_t, int , const structsched_param *); intpthread_detach(pthread_t);
Threads attributes NAME pthread_attr_destroy, pthread_attr_init - destroy and initialize the thread attributes object SYNOPSIS #include <pthread.h> int pthread_attr_destroy(pthread_attr_t *attr);int pthread_attr_init(pthread_attr_t *attr);
Threads attributes - example pthread_attr_tattr; size_tsize = 1024; if (pthread_attr_init(&attr)) ASSERT(false); if (pthread_attr_getstacksize(&attr, &size)) ASSERT(false); /*createnewthread*/ if (pthread_attr_destroy(&attr)) ASSERT(false);
Canceling threads NAME pthread_cancel- function requests that thread be cancelled. SYNOPSIS #include <pthread.h> int pthread_cancel(pthread_tthread);
Canceling threads NAME pthread_cleanup_push, pthread_cleanup_pop- pushes the handler routine and argument onto the calling thread’scancellation cleanup stackorremoves the routine at the top of the calling thread’s cancellationcleanup stack and invokes it if execute is non-zero. SYNOPSIS #include <pthread.h> voidpthread_cleanup_push(void (*routine)(void *), void *arg);voidpthread_cleanup_pop(int execute);
Canceling threads NAME pthread_cleanup_push, pthread_cleanup_pop- pushes the handler routine and argument onto the calling thread’scancellation cleanup stackorremoves the routine at the top of the calling thread’s cancellationcleanup stack and invokes it if execute is non-zero. SYNOPSIS #include <pthread.h> voidpthread_cleanup_push(void (*routine)(void *), void *arg);voidpthread_cleanup_pop(int execute);
Canceling threads NAME pthread_setcanceltype, pthread_setcancelstate - This function both sets the calling thread’s cancellabilitytype/state totype/state and returns the previous value in oldtype/oldstate. Legal valuesfor type are PTHREAD_CANCEL_DEFERRED and PTHREAD_CANCEL_ASYNCHRONOUS. Legal values for state arePTHREAD_CANCEL_ENABLED and PTHREAD_CANCEL_DISABLED. SYNOPSIS #include <pthread.h> int pthread_setcanceltype(inttype, int *oldtype); int pthread_setcancelstate(int state, int *oldstate);