0% found this document useful (0 votes)
2 views

6 Pthreads

Uploaded by

manjunathsg85
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

6 Pthreads

Uploaded by

manjunathsg85
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 36

Pthreads

CS 241 Lecture 8
(R: Chapter 12 pp 409-443)

Andrew Bennett

08/13/24 CS241 © 2005 Roy Campbell, All R 1


ights Reserved
Contents
 Processes vs Threads
 HOWTO: pthreads
 pthread attributes

08/13/24 CS241 © 2005 Roy Campbell, All R 2


ights Reserved
Overview: threads vs. processes (created with fork)

Processes created with


Property Threads of a process Ordinary function calls
fork

variables get copies of all variables share global variables share global variables

share the same process ID but share the same process ID


IDs get new process IDs
have unique thread ID (and thread ID)

Must explicitly May communicate with return May communicate with


communicate, e.g.pipes value return value
Communication
or use small integer or shared variables or shared variables
return value if done carefully (don't have to be careful)

Parallelism (one
Concurrent Concurrent Sequential
CPU)
Parallelism May be executed Kernel threads may be executed
Sequential
(multiple CPUs) simultaneously simultaneously

08/13/24 CS241 © 2005 Roy Campbell, All R 3


ights Reserved
Thread components
A thread has its own program counter and stack,
but shares a number of resources with its process
and other threads of the process:
 address space: code and global variables
 open files
 semaphores
 signals
 timers
 process ID

08/13/24 CS241 © 2005 Roy Campbell, All R 4


ights Reserved
 When a new thread is created it runs
concurrently with the creating
process.

 When creating a thread you indicate


which function the thread should
execute.

08/13/24 CS241 © 2005 Roy Campbell, All R 5


ights Reserved
Normal function call

08/13/24 CS241 © 2005 Roy Campbell, All R 6


ights Reserved
Threaded function call

08/13/24 CS241 © 2005 Roy Campbell, All R 7


ights Reserved
 A function that is used as a thread must have a
special format.

 It takes a single parameter of type pointer to void and


returns a pointer to void.
 The parameter type allows any pointer to be passed.

 This can point to a structure, so in effect, the function


can use any number of parameters.

 We will discuss the meaning of the return value later.

08/13/24 CS241 © 2005 Roy Campbell, All R 8


ights Reserved
The processfd function used above might have prototype:

void *processfd(void *arg);

Instead of passing the file descriptor to be monitored directly,


we pass a pointer to it.
The function my access the parameter as follows:

int fd;
fd = *((int *)arg);

08/13/24 CS241 © 2005 Roy Campbell, All R 9


ights Reserved
POSIX function description
pthread_canc
terminate another thread
el
pthread_creat
create a thread
e
pthread_deta
set thread to release resources
ch
pthread_equa
test two thread IDs for equality
l
pthread_exit exit a thread without exiting process
pthread_kill
08/13/24 send a signal to a thread
CS241 © 2005 Roy Campbell, All R 10
ights Reserved
 Most POSIX functions return 0 on
success and a nonzero error code on
failure.
 They do not set errno but the value
returned when an error occurs has
the value that errno would have.
 None of the POSIX thread functions
ever return the error EINTR.

08/13/24 CS241 © 2005 Roy Campbell, All R 11


ights Reserved
The Thread ID

Each thread has an id of type pthread_t.

On most systems this is just an integer (like a process ID)


but it does not have to be.
A thread can get its ID with pthread_self and IDs
can be compared with pthread_equal

pthread_t pthread_self(void);
int pthread_equal(thread_t t1, pthread_t t2);

08/13/24 CS241 © 2005 Roy Campbell, All R 12


ights Reserved
Creating a thread

A thread is created with pthread_create

int pthread_create(pthread_t *restrict thread,


const pthread_attr_t *restrict attr,
void *(*start_routine)(void *), void *restrict arg);

•The creating process (or thread) must provide a location for storage
of the thread id.
•We will discuss thread attributes later. For now, pass a null pointer to
indicate the default attributes.
•The third parameter is just the name of the program for the thread to
run.
•The last parameter is a pointer to the arguments.

08/13/24 CS241 © 2005 Roy Campbell, All R 13


ights Reserved
Detaching and joining

 A thread exits when its function returns.


There are other ways for a thread to exit.
 Just like with processes, some of the threads
resources stay around until it has been waited for or
its process terminates.
 You wait for a thread with pthread_join.
 You can make a thread release its resources when it
terminates by making it a detached thread.
 A detached thread cannot be joined.
 One way to make a thread detached is with
pthread_detach
int pthread_detach(pthread_t thread);

08/13/24 CS241 © 2005 Roy Campbell, All R 14


ights Reserved
How to make a thread detached
void *processfd(void *arg);

int error;
int fd
pthread_t tid;

if (error = pthread_create(&tid, NULL, processfd, &fd))


fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
else if (error = pthread_detach(tid))
fprintf(stderr, "Failed to detach thread: %s\n", strerror(error));

08/13/24 CS241 © 2005 Roy Campbell, All R 15


ights Reserved
How a thread can detach itself
void *detachfun(void *arg) {
int i = *((int *)(arg));
if (!pthread_detach(pthread_self()))
return NULL;
fprintf(stderr, "My argument is %d\n", i);
return NULL;
}

08/13/24 CS241 © 2005 Roy Campbell, All R 16


ights Reserved
 A thread can pass a value to another thread through its
return value.
 This is something like the return value that a parent gets
from its child through its exit status.
 You are not restricted to a small integer as with processes.
 The return value is a pointer to arbitrary data.
 Since the threads all share an address space, this is simple
to do.
 However, you must take care. Examples later.
 The pthread_join function suspends the calling function until
a specific thread has completed.
 There is no way to join the first of several threads that have
completed.
int pthread_join(pthread_t thread, void **value_ptr);

08/13/24 CS241 © 2005 Roy Campbell, All R 17


ights Reserved
int error;
int *exitcodep;
pthread_t tid;

if (error = pthread_join(tid, &exitcodep))


fprintf(stderr, "Failed to join thread: %s\n", strerror(error));
else
fprintf(stderr, "The exit code was %d\n", *exitcodep);

08/13/24 CS241 © 2005 Roy Campbell, All R 18


ights Reserved
Exiting and Cancellation

A process can terminate when:


•it calls exit directly
•one of its threads calls exit
•it executes return from main
•it receives a signal
In any of these cases, all threads of the process
terminate.

08/13/24 CS241 © 2005 Roy Campbell, All R 19


ights Reserved
When a thread is done, it can call return from its main function (the
one used by pthread_create) or it can call pthread_exit

void pthread_exit(void *value_ptr);

One thread can request that another exit with pthread_cancel

int pthread_cancel(pthread_t thread);

The pthread_cancel returns after making the request.


A successful return does not mean that the target thread has
terminated or even that it eventually will terminate as a result of the
request.

08/13/24 CS241 © 2005 Roy Campbell, All R 20


ights Reserved
POSIX functions that are always cancellation points.

accept mq_timedsend putpmsg sigsuspend


sigtimedwa
aio_suspend msgrcv pwrite
it
clock_nanoslee
msgsnd read sigwait
p
close msync readv sigwaitinfo
connect nanosleep recv sleep
creat open recvfrom system
fcntl* pause recvmsg tcdrain
fsync poll select usleep
sem_timedw
getmsg pread wait
ait
pthread_cond_timedw
getpmsg sem_wait waitid
ait
lockf pthread_cond_wait send waitpid
mq_receive pthread_join sendmsg write
mq_send pthread_testcancel sendto writev

mq_timedreceiv
e * only when
putmsg
the command
sigpause
is F_SETLKW
08/13/24 CS241 © 2005 Roy Campbell, All R 21
ights Reserved
Passing parameters and returning
values
You can pass multiple parameters to a thread
by passing a pointer, such as an array, to
the thread when it is created.
Care must be taken in receiving return values.
 The terminating thread passes a pointer to
the joining thread.
 They share the same address space.
 The return value must exist after the thread
terminates.
 You cannot use an automatic variable in the
thread for the return value

08/13/24 CS241 © 2005 Roy Campbell, All R 22


ights Reserved
User Threads and Kernel
Threads
User-level threads run on top of an operating system.
•Threads are invisible to the kernel.
•Link to a special library of system calls that prevent
blocking
•Have low overhead
•CPU-bound threads can block other threads
•Can only use one processor at a time

08/13/24 CS241 © 2005 Roy Campbell, All R 23


ights Reserved
Kernel-level threads are part of the
OS.
 Kernel can schedule threads like it
does processes.
 Multiple threads of a process can run
simultaneously on multiple CPUs.
 Synchronization more efficient than
for processes but less than for user-
level threads.

08/13/24 CS241 © 2005 Roy Campbell, All R 24


ights Reserved
08/13/24 CS241 © 2005 Roy Campbell, All R 25
ights Reserved
08/13/24 CS241 © 2005 Roy Campbell, All R 26
ights Reserved
08/13/24 CS241 © 2005 Roy Campbell, All R 27
ights Reserved
Thread Attributes
 Create an attribute object (initialize it with
default properties).
 Modify the properties of the attribute
object.
 Create a thread using the attribute object.
 The object can be changed or reused
without affecting the thread.
 The attribute object affects the thread only
at the time of thread creation.

08/13/24 CS241 © 2005 Roy Campbell, All R 28


ights Reserved
Settable properties of thread attributes
property function

attribute objects pthread_attr_destroy

pthread_attr_init

state pthread_attr_getdetachstate

pthread_attr_setdetachstate

stack pthread_attr_getguardsize

pthread_attr_setguardsize

pthread_attr_getstack

pthread_attr_setstack

scheduling pthread_attr_getinheritsched

pthread_attr_setinheritsched

pthread_attr_getschedparam

pthread_attr_setschedparam

pthread_attr_getschedpolicy

pthread_attr_setschedpolicy

pthread_attr_getscope

pthread_attr_setscope

08/13/24 CS241 © 2005 Roy Campbell, All R 29


ights Reserved
Initialize or destroy an attribute with:

int pthread_attr_destroy(pthread_attr_t *attr);


int pthread_attr_init(pthread_attr_t *attr);

08/13/24 CS241 © 2005 Roy Campbell, All R 30


ights Reserved
Create a detached thread

int error, fd;


pthread_attr_t tattr;
pthread_t tid;

if (error = pthread_attr_init(&tattr))
fprintf(stderr, "Failed to create attribute object: %s\n",

strerror(error));
else if (error = pthread_attr_setdetachstate(&tattr,
PTHREAD_CREATE_DETACHED))
fprintf(stderr, "Failed to set attribute state to detached: %s\n",
strerror(error));
else if (error = pthread_create(&tid, &tattr, processfd, &fd))
fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
08/13/24 CS241 © 2005 Roy Campbell, All R 31
ights Reserved
The thread stack
You can set a location and size for the thread stack.

int pthread_attr_getstack(const pthread_attr_t *restrict attr,


void **restrict stackaddr, size_t *restrict stacksize);
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
size_t stacksize);

Some systems allow you to set a guard for the stack so that an
overflow into the guard area can generate a SIGSEGV signal.

int pthread_attr_getguardsize(const pthread_attr_t *restrict attr,


size_t *restrict guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr,
size_t guardsize);

08/13/24 CS241 © 2005 Roy Campbell, All R 32


ights Reserved
Thread scheduling
The contentionscope can be PTHREAD_SCOPE_PROCESS or
PTHREAD_SCOPE_SYSTEM.
The scope determines whether the thread competes with other
threads of the process or with other processes in the system.

int pthread_attr_getscope(const pthread_attr_t *restrict attr,


int *restrict contentionscope);
int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);

08/13/24 CS241 © 2005 Roy Campbell, All R 33


ights Reserved
Create a thread that contends with
other processes
int error;
int fd;
pthread_attr_t tattr;
pthread_t tid;
if (error = pthread_attr_init(&tattr))
fprintf(stderr, "Failed to create an attribute object:%s\n",
strerror(error));
else if (error = pthread_attr_setscope(&tattr,
PTHREAD_SCOPE_SYSTEM))
fprintf(stderr, "Failed to set scope to system:%s\n",
strerror(error));
else if (error = pthread_create(&tid, &tattr, processfd, &fd))
fprintf(stderr, "Failed to create a thread:%s\n",
strerror(error));

08/13/24 CS241 © 2005 Roy Campbell, All R 34


ights Reserved
POSIX functions that are not
required to be thread-safe.
asctime fcvt getpwnam nl_langinfo

basename ftw getpwuid ptsname

catgets gcvt getservbyname putc_unlocked

crypt getc_unlocked getservbyport putchar_unlocked

ctime getchar_unlocked getservent putenv

dbm_clearerr getdate getutxent pututxline

dbm_close getenv getutxid rand

dbm_delete getgrent getutxline readdir

dbm_error getgrgid gmtime setenv

dbm_fetch getgrnam hcreate setgrent

dbm_firstkey gethostbyaddr hdestroy setkey

dbm_nextkey gethostbyname hsearch setpwent

dbm_open gethostent inet_ntoa setutxent

dbm_store getlogin l64a strerror

dirname getnetbyaddr lgamma strtok

dlerror getnetbyname lgammaf ttyname

drand48 getnetent lgammal unsetenv

ecvt getopt localeconv wcstombs

encrypt getprotobyname localtime wctomb

endgrent getprotobynumber lrand48

endpwent getprotoent mrand48

endutxent getpwent nftw

08/13/24 CS241 © 2005 Roy Campbell, All R 35


ights Reserved
Summary
 pthreads
 pthread functionality and attributes

08/13/24 CS241 © 2005 Roy Campbell, All R 36


ights Reserved

You might also like