Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
System Programming
Threads
What is a Threads
1
What is a Threads
2
Processes vs. Threads
Thread Execution
3
Thread Pros and Cons
• Pros:
• Responsiveness
• Resource Sharing
• Economy
• Utilization of MP Architectures
• Cons:
• Extra caution when programming threads
• Complexity of extending process concepts (e.g. when
forking a process should all threads be created? How are
signals handled?)
Multithreading Models
4
Multithreading Models
• Many-to-One:
• Many user-level threads mapped
to single kernel thread
• Managed in the user space by the
thread library (efficient)
• Used on systems that do not
support kernel threads
• Entire process blocks in case one
of its threads block (-ve)
• True concurrency is not fully
achieved (-ve)
Multithreading Models
• One-to-One:
• Each user-level thread maps to kernel thread
• A process does not block if one of its threads block
• Better utilizes multiprocessors (each thread runs on its
own processor)
• Too many threads consume system resources (-ve)
5
Multithreading Models
• Many-to-Many:
• Multiplexes user threads to a
smaller or equal number of
kernel threads
• Developer can create as many
user threads
• The corresponding kernel
threads can run in parallel on a
multiprocessor
6
Thread families
POSIX Threads
7
POSIX Threads
Thread Manipulation
1. Thread creation
• Each thread is identified by a thread ID
• Upon creation, a thread executes a function
• The function takes a single parameter of type void*
(can be used to pass data to the thread)
• The function returns void* (can be used to pass data
from thread back to creator process)
• Thread attributes control details of how the
thread interacts with the rest of the program
8
Thread Creation
NULL: default
thread ID is attributes
stored
thread function
Passed as argument to
thread function
Thread Creation
9
Thread Attributes
Thread Manipulation
2. Thread termination
• Causes the current thread to exit and free any thread-
specific resources it is taking
Usually NULL, anything else
might be out of scope
10
Example 1
#include <pthread.h>
#include <stdio.h>
Void main ()
{
pthread_t thread_id;
pthread_create (&thread_id,NULL,&Display_0s,NULL);
while(1)
fputc (‘1 ’,stderr);
}
Example 2
#include <stdio.h>
struct char_print_parms
{
char character;
int count;
};
11
Example 2
#include <pthread.h>
#include <stdio.h>
void main ()
{
pthread_t thread_1, thread_2;
struct char_print_parms thread_1_args;
struct char_print_parms thread_2_args;
thread_1_args.character =’0 ’;
thread_1_args.count = 1000;
pthread_create (&thread_1,NULL,&char_print,&thread_1_args);
thread_2_args.character =’1 ’;
thread_2_args.count = 2000;
pthread_create (&thread_2,NULL,&char_print,&thread_2_args);
}
Thread Manipulation
3. Joining threads
• Suspends the calling thread until target thread
terminates
thread ID to
wait for
int pthread_join( pthread_t thread,
void **thread_return)
12
Example 2
#include <pthread.h>
#include <stdio.h>
void main ()
{
pthread_t thread_1, thread_2;
struct char_print_parms thread_1_args;
struct char_print_parms thread_2_args;
thread_1_args.character =’0 ’;
thread_1_args.count = 1000;
pthread_create (&thread_1,NULL,&char_print,&thread_1_args);
thread_2_args.character =’1 ’;
thread_2_args.count = 2000;
pthread_create (&thread_2,NULL,&char_print,&thread_2_args);
pthread_join (thread_1,NULL);
pthread_join (thread_2,NULL);
Example 3
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
char message[] = “Hello World”;
void *thread_function(void *arg)
{
printf(“thread_function is running.
Argument was %s\n”, (char *)arg);
sleep(3);
strcpy(message, “Bye!”);
pthread_exit(“Thank you for the CPU
time”);
}
13
Example 3
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0) {
perror(“Thread creation failed”);
exit(EXIT_FAILURE);
}
printf(“Waiting for thread to finish...\n”);
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror(“Thread join failed”);
exit(EXIT_FAILURE);
}
printf(“Thread joined, it returned %s\n”, (char *)thread_result);
printf(“Message is now %s\n”, message);
exit(EXIT_SUCCESS);
}
14
Example 4
#include <pthread.h>
void* thread_function (void* thread_arg)
{
/* Do work here... */
}
int main ()
{
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
pthread_create (&thread, &attr, &thread_function, NULL);
pthread_attr_destroy (&attr);
/* Do work here... */
/* No need to join the second thread. */
return 0;
}
User Kernel
User manages threads Kernel creates and manages
threads
A thread may monopolize Kernel schedules each
the time slice of the process thread within the time slice
of a process
Switching is fast Switching has more
overhead
15
Java Example
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
Java Example
class TwoThreadsTest {
public static void main (String
args[]) {
new
SimpleThread("Jamaica").start();
new
SimpleThread("Fiji").start();
}
}
16
Java Example
0 Jamaica
0 Fiji
1 Fiji
1 Jamaica
2 Jamaica
2 Fiji
3 Fiji
3 Jamaica
4 Jamaica
4 Fiji
5 Jamaica
5 Fiji
6 Fiji
6 Jamaica
7 Jamaica
7 Fiji
8 Fiji
9 Fiji
8 Jamaica
DONE! Fiji
9 Jamaica
DONE! Jamaica
Synchronization (Mutexes)
17
Synchronization (Mutexes)
• #include <pthread.h>
• pthread_mutex_t mutex;
• int pthread_mutex_init(pthread_mutex_t
*mutex, const pthread_mutexattr_t
• *mutexattr);
• int pthread_mutex_lock(pthread_mutex_t
*mutex));
• int pthread_mutex_unlock(pthread_mutex_t
*mutex);
• int pthread_mutex_destroy(pthread_mutex_t
*mutex);
Example 5
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t work_mutex; /* protects both work_area and
time_to_exit */
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;
18
Example 5
void *thread_function(void *arg) {
sleep(1);
pthread_mutex_lock(&work_mutex);
while(strncmp(“end”, work_area, 3) != 0) {
printf(“You input %d characters\n”, strlen(work_area) -1);
work_area[0] = ‘\0’;
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
while (work_area[0] == ‘\0’ ) {
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
time_to_exit = 1;
work_area[0] = ‘\0’;
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}
Example 5
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_mutex_init(&work_mutex, NULL);
if (res != 0) {
perror(“Mutex initialization failed”);
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror(“Thread creation failed”);
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&work_mutex);
printf(“Input some text. Enter ‘end’ to finish\n”);
19
Example 5
while(!time_to_exit) {
fgets(work_area, WORK_SIZE, stdin);
pthread_mutex_unlock(&work_mutex);
while(1) {
pthread_mutex_lock(&work_mutex);
if (work_area[0] != ‘\0’) {
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else {
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf(“\nWaiting for thread to finish...\n”);
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror(“Thread join failed”);
exit(EXIT_FAILURE);
}
printf(“Thread joined\n”);
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}
Synchronization (Semaphores)
#include <semaphore.h>
• int sem_init(sem_t *sem, int
pshared, unsigned int value);
• int sem_wait(sem_t * sem);
• int sem_post(sem_t * sem);
• int sem_destroy(sem_t * sem);
20
sem_init
Control Functions
21
Control Functions
Example 5
sem_t bin_sem;
22
Example 5
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = sem_init(&bin_sem, 0, 0);
res = pthread_create(&a_thread, NULL,
thread_function, NULL);
printf(“Input some text. Enter ‘end’ to
finish\n”);
while(strncmp(“end”, work_area, 3) != 0) {
fgets(work_area, WORK_SIZE, stdin);
sem_post(&bin_sem);
}
printf(“\nWaiting for thread to finish...\n”);
res = pthread_join(a_thread, &thread_result);
printf(“Thread joined\n”);
sem_destroy(&bin_sem);
exit(EXIT_SUCCESS);
}
23