Presentation is loading. Please wait.

Presentation is loading. Please wait.

C Threads and Semaphores

Similar presentations


Presentation on theme: "C Threads and Semaphores"— Presentation transcript:

1 C Threads and Semaphores

2 Posix Threads Set of library services to access OS threads
Standardized across all compliant OSs Although, porting issues can occur with parameters (stack size, scheduling) Services allow for creation, destruction, waiting, etc. No facility for shared memory Can pass a single data argument on creation and return a single data argument on exit Otherwise, use shared memory segments

3 Thread Management Functions
pthread_attr_init Attribute set the threads properties in the OS – stack size, scheduling Values can be set/get by calling pthread_attr_get/setXXX() pthread_create Creates the thread using initialization attributes and an entry point label for the start routine pthread_exit Exits the calling thread and makes the paramater available to any other threads the join this thread Called implicitly when thread’s start routing returns pthread_join Suspends the calling thread until the target thread terminates – also reads termination code

4 Initial Attributes Attributes will vary across different OSes
When porting, don’t let values default, or look at attributes when errors Attributes detachedstate joinable or detached (non-joinable) Another thread can synchronize on thread termination and read term. Code schedpolicy SCHED_OTHER, SCHED_RR, SCHED_FIFO Other is non-realtime, RR and FIFO are realtime schedparam for schedule policy Priority, replenish period, initial time budget inheritsched Inherit parent’s schedule or use those provided scope Scheduling contention scope Scheduling decision based on all threads in system or based on process

5 pthread_create Create creates a new thread using OS services
include <pthread.h> int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); Create creates a new thread using OS services Attributes specify thread properties NULL specifies defaults – may change when porting to different OSs typedef struct { int is_initialized; void *stackaddr; int stacksize; int contentionscope; int inheritsched; int schedpolicy; struct sched_param schedparam; /* P1003.4b/D8, p. 54 adds cputime_clock_allowed attribute. */ #if defined(_POSIX_THREAD_CPUTIME) int cputime_clock_allowed; /* see time.h */ #endif int detachstate; } pthread_attr_t;

6 PThread Example Thread’s main method
Thread accepts an argument, prints it, and changes the value to 1000 If we are expecting someone to join us, pass back a string void *thread_main(void *arg) { printf("thread_main: Received %d\n", *( (int *)arg)); *( (int *)arg) = 1000; printf("thread_main: Finished\n"); #ifdef PTHREAD_JOIN pthread_exit("FROM PTHREAD_EXIT"); // returned from pthread_join #endif return "FROM THREAD RETURN"; // returned from pthread_join if no } // explicit pthread_exit() call

7 PThread Example Main programming creating the thread
Pass in the 100 and display the modified value If we are joining, join thread (blocking until completion and print response int main() { pthread_t thread; pthread_attr_t pthread_attr; printf("Thread Example main starting\n"); int *arg = (int *) malloc(sizeof (int)); *arg = 100; pthread_attr_init(&pthread_attr); pthread_create(&thread, &pthread_attr, &thread_main, arg); #ifdef PTHREAD_JOIN void **threadReturn; pthread_join(thread, threadReturn); // (optional) wait for thread to end printf("main: Thread returned *%s*\n", (char *) *threadReturn); #endif printf("main: Thread finished, arg is now %d\n", *arg); return 0; }

8 Initializing Threads The function creating the thread can pass initialization data Must be data that is either global or on the heap – no stack! Commonly allocated on heap and passed to stack If allocated on heap – who frees the memory!!! Threads must know if they are to free memory when leaving

9 Semaphores Protected variable for restricting access to shared resources Initialized to a number of resources it controls Binary semaphore is special case of 1 resource Common methods P(s) locks semaphore; V(s) releases semaphore Issues Semaphore separate from resource Must trust all clients to use semaphore properly

10 Semaphore Functions int sem_init(sem_t *sem, int pshared, unsigned int value); Initialize the semaphore for usage, value is set by value Allows a semaphore to let multiple threads inside Pshared allows semaphore to be shared across processes (1=true) Returns -1 on failure with errorno set int sem_destroy(sem_t *sem); Destroys the semaphore, freeing OS requires required for it Call only when no threads a blocked on the semaphore

11 Semaphore Functions Lock a semaphore, blocks if value is currently 0
int sem_wait(sem_t *sem); Lock a semaphore, blocks if value is currently 0 sem_trywait() will not block if 0 Returns -1 on failure with errorno set int sem_post(sem_t *sem); Unlocks the semaphore, allowing other threads to enter Theads is chosen by scheduling policy – see link below

12 PThread Example Multiple threads access a common resource XYZ
// Structure for passing threads their initial data typedef struct { sem_t*sem; int id; } thread_init_data; int XYZ;// global resource accessed by threads void *thread_main(void *init_data) { thread_init_data mydata = *( (thread_init_data *) init_data); printf("thread_main (%d): Started\n", mydata.id); sem_wait(mydata.sem); XYZ = XYZ + 1; sleep(2);// simulate processing time printf("thread_main (%d): Finished x = %d\n", mydata.id, x); sem_post(mydata.sem); free (init_data);// main malloc-ed our argument, we must free it return NULL; }

13 PThread Example int main() { int i; pthread_t thread[3];
pthread_attr_t pthread_attr; sem_t *the_real_sem; the_real_sem = malloc (sizeof(sem_t)); sem_init(the_real_sem, 0, 1); // no processes, 1 thread at a time printf("Thread Example main starting\n"); pthread_attr_init(&pthread_attr); for (i=0; i < 3; i++) { thread_init_data *init = (thread_init_data *) malloc (sizeof(thread_init_data)); init -> id = i; init -> sem = the_real_sem; pthread_create(&thread[i], &pthread_attr, &thread_main, init); } printf("main: launched all threads\n"); // Wait for threads to finish, program terminates if main completes sleep(9); return 0; Declare and allocate semaphore Create 3 threads, passing each the semaphore and an id

14 Compiling Example Compilation (may) require non-standard libraries
Recall the –l<library> compiler argument Compiling for the arm Libraries located in /opt/crosstool/arm-unknown-linux-gnu/gcc glibc-2.3.2/arm-unknown-linux-gnu/lib libpthread.a contains the pthread code Compile as > arm-gcc ThreadSafeExample.c -lpthread

15 Priority Inversion Use of semaphores can cause problems with priorities in real-time systems See below: Common solution is to raise priority of any lower-priority thread that holds a resource required by a higher-priority thread Realtime applications may encounter priority inversion when using semaphores. The problem occurs when a high priority thread "locks" (that is, waits on) a semaphore that is about to be "unlocked" (that is, posted) by a low priority thread, but the low priority thread is preempted by a medium priority thread. This scenario leads to priority inversion; a high priority thread is blocked by lower priority threads for an unlimited period of time. During system design, realtime programmers must take into account the possibility of this kind of priority inversion. They can deal with it in a number of ways, such as by having critical sections that are guarded by semaphores execute at a high priority, so that a thread cannot be preempted while executing in its critical section.

16 Shared Memory Segments
Efficient mechanism for inter-process communication Other option is sockets

17 Shared Memory Functions
int shmget(key_t key, size_t size, int shmflg); Creates or gets a reference to a shared memory segment Key identifies SM segment Use same key to obtain access to same memory Use IPC_PRIVATE for a Allows a semaphore to let multiple threads inside Shmflg IPC_CREAT creates size byte memory if key does not exist If creating, the lower order bits of shmflg indicate permissions Returns SM id on success, -1 on failure with errorno set

18 Shared Memory Functions
void *shmat(int shmid, const void *shmaddr, int shmflg); Attaches a shared memory segment to address space of calling process Shmid is segment id obtained from shmget Shmaddr can be used as the address, or, if shmaddr is NULL, the system selects the first available address shmflg SHM_RDONLY attaches for reading, R/W otherwise Returns segment’s start address; -1 on error with errno set


Download ppt "C Threads and Semaphores"

Similar presentations


Ads by Google