62
Lecture 08: Programming with PThreads: PThreads basics, Mutual Exclusion and Locks, and Examples CSCE 790: Parallel Programming Models for Multicore and Manycore Processors Department of Computer Science and Engineering Yonghong Yan [email protected] http://cse.sc.edu/~yanyh 1

Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

  • Upload
    others

  • View
    18

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Lecture08:ProgrammingwithPThreads:PThreads basics,MutualExclusionandLocks,

andExamplesCSCE790:ParallelProgrammingModelsforMulticoreandManycore Processors

DepartmentofComputerScienceandEngineeringYonghong Yan

[email protected]://cse.sc.edu/~yanyh

1

Page 2: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

OpenMP:WorksharingConstructs

2

for(i=0;i<N;i++) { a[i] = a[i] + b[i]; }

#pragma omp parallel shared (a, b)

{

int id, i, Nthrds, istart, iend;id = omp_get_thread_num();Nthrds = omp_get_num_threads();istart = id * N / Nthrds;iend = (id+1) * N / Nthrds;for(i=istart;i<iend;i++) { a[i] = a[i] + b[i]; }

}

#pragma omp parallel shared (a, b) private (i) #pragma omp for schedule(static)

for(i=0;i<N;i++) { a[i] = a[i] + b[i]; }

Sequential code

OpenMP parallel region

OpenMP parallel region and a worksharing for construct

Page 3: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

PThreads

• Processingelementabstractionforsoftware– PThreads– OpenMP/Cilk/othersruntimeusePThreads fortheir

implementation

• Thefoundationofparallelismfromcomputersystem

• TopicOverview– ThreadbasicsandthePOSIXThreadAPI– Threadcreation,terminationandjoining– Threadsafety– SynchronizationprimitivesinPThreads

Page 4: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• processes containinformationaboutprogramresourcesandprogramexecutionstate,including:– ProcessID,processgroupID,userID,andgroupID– Environment,Workingdirectory,Programinstructions– Registers,Stack,Heap– Filedescriptors,Signalactions– Sharedlibraries,Inter-processcommunicationtools(suchas

messagequeues,pipes,semaphores,orsharedmemory).

• Whenwerunaprogram,aprocessiscreated– E.g../a.out,./axpy,etc– fork()systemcall

OSReview:Processes

Page 5: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Threadsuse,andexistwithin,theprocessresources• Scheduledandrunasindependententities• Duplicateonlythebareessentialresourcesthatenablethemtoexistasexecutablecode

Threads

Page 6: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Athreadmaintainsitsown:– Stackpointer– Registers– Schedulingproperties(suchaspolicy

orpriority)– Setofpendingandblockedsignals– Threadspecificdata.

• Multiplethreadssharetheprocessresources

• Athreaddiesiftheprocessdies• "lightweight”forcreatingand

terminatingthreadsthatforprocesses

Threads

Page 7: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

WhatisaThreadinReal

• OSview– AnindependentstreamofinstructionsthatcanbescheduledtorunbytheOS.

• Softwaredeveloperview– A “procedure”thatrunsindependentlyfromthemainprogram

• Imaginemultiplesuchproceduresofmainrunsimultaneouslyand/orindependently

– Sequentialprogram:asinglestreamofinstructionsinaprogram.

– Multi-threadedprogram:aprogramwithmultiplestreams• Multiplethreadsareneededtousemultiplecores/CPUs

7

Page 8: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Threadas“functioninstance”

X=

Athread isasinglestreamofcontrolintheflowofaprogram:

for (i = 0; i < n; i++) y[i] = dot_product(row(A, i),b);

for (i = 0; i < n; i++) y[i] = create_thread(dot_product(row(A, i), b));

• thinkofthethreadasaninstanceofafunctionthatreturnsbeforethefunctionhasfinishedexecuting.

Page 9: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

POSIXthreads(PThreads)

• Threadsusedtoimplementparallelism insharedmemorymultiprocessorsystems,suchasSMPs

• Historically,hardwarevendorshaveimplementedtheirownproprietaryversionsofthreads– Portabilityaconcernforsoftwaredevelopers.

• ForUNIXsystems,astandardizedClanguagethreadsprogramminginterfacehasbeenspecifiedbytheIEEEPOSIX1003.1cstandard.– Implementationsthatadheretothisstandardarereferredto

asPOSIXthreads

9

Page 10: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThePOSIXThreadAPI

• CommonlyreferredtoasPThreads,POSIXhasemergedasthestandardthreadsAPI,supportedbymostvendors.– Implementedwithapthread.h header/includefileandathread

library

• Functionalities– Threadmanagement,e.g.creationandjoining– Threadsynchronizationprimitives

• Mutex• Conditionvariables• Reader/writerlocks• Pthread barrier

– Thread-specificdata

• TheconceptsdiscussedherearelargelyindependentoftheAPI– AppliedtootherthreadAPIs(NTthreads,Solaristhreads,Java

threads,etc.)aswell.

Page 11: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

PThread API

• #include <pthread.h>

• gcc -lpthread

11

Page 12: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Initially,main()programcomprisesasingle,defaultthread– Allotherthreadsmustbeexplicitlycreated

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void * arg);

• thread:Anopaque,uniqueidentifierforthenewthreadreturnedbythesubroutine• attr:Anopaque attributeobjectthatmaybeusedtosetthreadattributes

Youcanspecifyathreadattributesobject,orNULLforthedefaultvalues• start_routine:theCroutinethatthethreadwillexecuteonceitiscreated• arg:Asingleargumentthatmaybepassedtostart_routine.Itmustbepassedby

referenceasapointercastoftypevoid.NULLmaybeusedifnoargumentistobepassed.

ThreadCreation

Opaqueobject:Aletterisanopaqueobjecttothemailman,andsenderandreceiverknowtheinformation.

Page 13: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThreadCreation

• pthread_create createsanewthreadandmakesitexecutable,i.e.runimmediatelyintheory– canbecalledanynumberoftimesfromanywherewithinyourcode

• Oncecreated,threadsarepeers,andmaycreateotherthreads• Thereisnoimpliedhierarchyordependencybetweenthreads

13

Page 14: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

#include <pthread.h>#define NUM_THREADS5

void *PrintHello(void *thread_id) {long tid = (long)thread_id;printf("Hello World! It's me, thread #%ld!\n", tid);pthread_exit(NULL);

}

int main(int argc, char *argv[]) {pthread_t threads[NUM_THREADS];long t;

for(t=0;t<NUM_THREADS;t++) {printf("In main: creating thread %ld\n", t);int rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t );if (rc) {

printf("ERROR; return code from pthread_create() is %d\n", rc);exit(-1);

}}

pthread_exit(NULL);}

One possible output:

In main: creating thread 0In main: creating thread 1In main: creating thread 2In main: creating thread 3Hello World! It's me, thread #0!In main: creating thread 4Hello World! It's me, thread #1!Hello World! It's me, thread #3!Hello World! It's me, thread #2!Hello World! It's me, thread #4!

Example1:pthread_create

Page 15: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• pthread_exit isusedtoexplicitlyexitathread– Calledafterathreadhascompleteditsworkandisnolonger

requiredtoexist• Ifmain()finishesbeforethethreadsithascreated

– Ifexitswithpthread_exit(),theotherthreadswillcontinuetoexecute

– Otherwise,theywillbeautomaticallyterminatedwhenmain()finishes

• Theprogrammermayoptionallyspecifyaterminationstatus,whichisstoredasavoidpointerforanythreadthatmayjointhecallingthread

• Cleanup:thepthread_exit()routinedoesnotclosefiles– Anyfilesopenedinsidethethreadwillremainopenafterthethread

isterminated

TerminatingThreads

Page 16: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThreadAttributeint pthread_create(

pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void * arg);

• Attributecontainsdetailsabout– whetherschedulingpolicyisinheritedorexplicit– schedulingpolicy,schedulingpriority– stacksize,stackguardregionsize

• pthread_attr_init andpthread_attr_destroy areusedtoinitialize/destroythethreadattributeobject

• Otherroutinesarethenusedtoquery/setspecificattributesinthethreadattributeobject

16

Page 17: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Thepthread_create() routinepermitstheprogrammertopassone argumenttothethreadstartroutine

• Forcaseswheremultipleargumentsmustbepassed:– Createastructurewhichcontainsallofthearguments– Thenpassapointertotheobjectofthatstructureinthe

pthread_create()routine.– Allargumentsmustbepassedbyreferenceandcastto(void*)

• Makesurethatallpasseddataisthreadsafe:dataracing– itcannotbechangedbyotherthreads– Itcanbechangedinadeterminantway

• Threadcoordination

PassingArgumentstoThreads

Page 18: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

#include <pthread.h>#define NUM_THREADS 8

struct thread_data {int thread_id;char *message;

};

struct thread_data thread_data_array[NUM_THREADS];

void *PrintHello(void *threadarg) {int taskid;char *hello_msg;

sleep(1);struct thread_data *my_data = (struct thread_data *) threadarg;taskid = my_data->thread_id;hello_msg = my_data->message;printf("Thread %d: %s\n", taskid, hello_msg);pthread_exit(NULL);

}

Example2:ArgumentPassing

Page 19: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

int main(int argc, char *argv[]) {pthread_t threads[NUM_THREADS];int t;char *messages[NUM_THREADS];messages[0] = "English: Hello World!";messages[1] = "French: Bonjour, le monde!"; messages[2] = "Spanish: Hola al mundo"; messages[3] = "Klingon: Nuq neH!";messages[4] = "German: Guten Tag, Welt!"; messages[5] = "Russian: Zdravstvytye, mir!";messages[6] = "Japan: Sekai e konnichiwa!";messages[7] = "Latin: Orbis, te saluto!";

for(t=0;t<NUM_THREADS;t++) {struct thread_data * thread_arg = &thread_data_array[t];thread_arg->thread_id = t;thread_arg->message = messages[t];pthread_create(&threads[t], NULL, PrintHello, (void *) thread_arg);

}pthread_exit(NULL);

}

Example2:ArgumentPassing

Thread3:Klingon:Nuq neH!Thread0:English:HelloWorld!Thread1:French:Bonjour,lemonde!Thread2:Spanish:Hola almundoThread5:Russian:Zdravstvytye,mir!Thread4:German:Guten Tag,Welt!Thread6:Japan:Sekai ekonnichiwa!Thread7:Latin:Orbis,te saluto!

Page 20: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

WaitforThreadTermination

Suspendexecutionofcallingthreaduntilthread terminates#include <pthread.h>int pthread_join(

pthread_t thread,

void **value_ptr);• thread:thejoiningthread• value_ptr:ptr tolocationforreturncodeaterminatingthreadpassesto

pthread_exit

• Itisalogicalerrortoattemptsimultaneousmultiplejoinsonthesamethread20

Page 21: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

#include <pthread.h>#define NUM_THREADS 4

void *BusyWork(void *t) { int i;long tid = (long)t;double result=0.0;printf("Thread %ld starting...\n",tid);

for (i=0; i<1000000; i++) { result = result + sin(i) * tan(i);

}

printf("Thread %ld done. Result = %e\n",tid, result); pthread_exit((void*) t);

}

Example3:PThreads Joining

Page 22: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

int main (int argc, char *argv[]){

pthread_t thread[NUM_THREADS];pthread_attr_t attr;long t;void *status;

/* Initialize and set thread detached attribute */pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

for(t=0; t<NUM_THREADS; t++) {printf("Main: creating thread %ld\n", t);pthread_create(&thread[t], &attr, BusyWork, (void *)t);

}/* Free attribute and wait for the other threads */pthread_attr_destroy(&attr);for(t=0; t<NUM_THREADS; t++) {

pthread_join(thread[t], &status);printf(“Main: joined with thread %ld, status: %ld\n", t, (long)status);

}printf("Main: program completed. Exiting.\n");pthread_exit(NULL);

}

Example3:PThreads joiningMain:creatingthread0Main:creatingthread1Thread0starting...Main:creatingthread2Thread1starting...Main:creatingthread3Thread2starting...Thread3starting...Thread1done.Result=-3.153838e+06Thread0done.Result=-3.153838e+06Main:joinedwiththread0,status:0Main:joinedwiththread1,status:1Thread2done.Result=-3.153838e+06Main:joinedwiththread2,status:2Thread3done.Result=-3.153838e+06Main:joinedwiththread3,status:3Main:programcompleted.Exiting.

Page 23: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Allthreadshaveaccesstothesameglobal,sharedmemory• Threadsalsohavetheirownprivatedata• Programmersareresponsibleforsynchronizingaccess

(protecting)globallyshareddata.

SharedMemoryandThreads

Page 24: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThreadConsequences

24

• SharedState!– Accidentalchangestoglobalvariablescanbefatal.– Changesmadebyonethreadtosharedsystemresources(suchas

closingafile)willbeseenbyallotherthreads– Twopointershavingthesamevaluepointtothesamedata– Readingandwritingtothesamememorylocationsispossible– Thereforerequiresexplicitsynchronizationbytheprogrammer

• Manylibraryfunctionsarenotthread-safe– LibraryFunctionsthatreturnpointerstostaticinternalmemory.E.g.

gethostbyname()• Lackofrobustness

– Crashinonethreadwillcrashtheentireprocess

Page 25: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Thread-safeness:inanutshell,refersanapplication'sabilitytoexecutemultiplethreadssimultaneouslywithout"clobbering"shareddataorcreating"race"conditions

• Example:anapplicationcreatesseveralthreads,eachofwhichmakesacalltothesamelibraryroutine:– Thislibraryroutineaccesses/modifiesaglobalstructureor

locationinmemory.– Aseachthreadcallsthisroutineitispossiblethattheymaytry

tomodifythisglobalstructure/memorylocationatthesametime.

– Iftheroutinedoesnotemploysomesortofsynchronizationconstructstopreventdatacorruption,thenitisnotthread-safe.

Thread-safeness

Page 26: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Thread-safeness

Page 27: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Theimplicationtousersofexternallibraryroutines:

• Ifyouaren't100%certaintheroutineisthread-safe,thenyoutakeyourchanceswithproblemsthatcouldarise.

• Recommendation– Becarefulifyourapplicationuseslibrariesorotherobjectsthat

don'texplicitlyguaranteethread-safeness.– Whenindoubt,assumethattheyarenotthread-safeuntil

provenotherwise– Thiscanbedoneby"serializing"thecallstotheuncertain

routine,etc.

Thread-safeness

Page 28: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Example4:DataRacing

28

#include <pthread.h>#define NUM_THREADS5

void *PrintHello(void *thread_id) { /* thread func */long tid = *((long*)thread_id);printf("Hello World! It's me, thread #%ld!\n", tid);pthread_exit(NULL);

}

int main(int argc, char *argv[]) {pthread_t threads[NUM_THREADS];long t;for(t=0;t<NUM_THREADS;t++) {

printf("In main: creating thread %ld\n", t);int rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t );if (rc) {

printf("ERROR; return code from pthread_create() is %d\n", rc);exit(-1);

}}

pthread_exit(NULL);}

Inmain:creatingthread0Inmain:creatingthread1Inmain:creatingthread2Inmain:creatingthread3HelloWorld!It'sme,thread#3!HelloWorld!It'sme,thread#3!HelloWorld!It'sme,thread#3!Inmain:creatingthread4HelloWorld!It'sme,thread#4!HelloWorld!It'sme,thread#5!

Page 29: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Theprimarymotivation– Torealizepotentialprogramperformancegains

• Comparedtothecostofcreatingandmanagingaprocess– A threadcanbecreatedwithmuchlessOSoverhead

• Managingthreadsrequiresfewersystemresourcesthanmanagingprocesses

• Allthreadswithinaprocesssharethesameaddressspace• Inter-threadcommunicationismoreefficientand,inmanycases,

easiertousethaninter-processcommunication

WhyPThreads (notprocesses)?

Page 30: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Timingresultsforthefork() subroutineandthepthreads_create() subroutine– Timingsreflect50,000process/threadcreations– unitsareinseconds– nooptimizationflags

pthread_create vs fork

Page 31: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Potentialperformancegainsandpracticaladvantagesovernon-threadedapplications:– OverlappingCPUworkwithI/O

• Forexample,aprogrammayhavesectionswhereitisperformingalongI/Ooperation

• WhileonethreadiswaitingforanI/Osystemcalltocomplete,CPUintensiveworkcanbeperformedbyotherthreads.

• Priority/real-timescheduling– Taskswhicharemoreimportantcanbescheduledtosupersedeor

interruptlowerprioritytasks.

• Asynchronouseventhandling– Taskswhichserviceeventsofindeterminatefrequencyanddurationcanbe

interleaved– Forexample,awebservercanbothtransferdatafrompreviousrequests

andmanagethearrivalofnewrequests.

Whypthreads

Page 32: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

AXPYwithPThreads

• y=α·x+y– x andy arevectorsofsizeN

• InC,x[N],y[N]– α isscalar

• Decompositionandmappingtopthreads

32

Ataskwillbemappedtoapthread

Page 33: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

AXPYwithPThreads

33

Page 34: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

DataRacinginaMultithreadProgramConsider:/* each thread to update shared variable best_cost */

if (my_cost < best_cost) best_cost = my_cost;

– twothreads,– theinitialvalueofbest_cost is100,– thevaluesofmy_cost are50and75forthreadst1andt2

best_cost = my_cost;

• Thevalueofbest_cost couldbe50or75!• Thevalue75doesnotcorrespondtoanyserializationofthetwo

threads.

34

T1 T2

if (my_cost (50) < best_cost)

best_cost = my_cost;

if (my_cost (75) < best_cost)

best_cost = my_cost;

Page 35: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

CriticalSectionandMutualExclusion

• Criticalsection=asegmentthatmustbeexecutedbyonlyonethreadatanytime

• Mutex locksprotectcriticalsectionsinPthreads– lockedandunlocked– Atanypointoftime,onlyonethreadcanacquireamutex lock

• Usingmutex locks– requestlockbeforeexecutingcriticalsection– entercriticalsectionwhenlockgranted– releaselockwhenleavingcriticalsection

if (my_cost < best_cost)best_cost = my_cost;

35

Page 36: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

MutualExclusionusingPthread Mutexint pthread_mutex_lock (pthread_mutex_t *mutex_lock); int pthread_mutex_unlock (pthread_mutex_t *mutex_lock); int pthread_mutex_init (pthread_mutex_t *mutex_lock,

const pthread_mutexattr_t *lock_attr);

pthread_mutex_t cost_lock;int main(){

...pthread_mutex_init(&cost_lock,NULL);pthread_create(&thhandle,NULL,find_best,…)

...}void*find_best(void*list_ptr){...pthread_mutex_lock(&cost_lock);//enterCSif(my_cost <best_cost)best_cost =my_cost;

pthread_mutex_unlock(&cost_lock);//leaveCS}

CriticalSection

pthread_mutex_lock blocksthecallingthreadifanotherthreadholdsthelock

Whenpthread_mutex_lock callreturns1. Mutex islocked,enterCS2. Anyotherlockingattempt(callto

thread_mutex_lock)willcausetheblockingofthecallingthread

Whenpthread_mutex_unlock returns1. Mutex isunlocked,leaveCS2. Onethreadwhoblockson

thread_mutex_lock callwillacquirethelockandenterCS

36

Page 37: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Producer-ConsumerUsingLocksConstrains:• Theproducerthreads

– mustnotoverwritethesharedbufferwhentheprevioustaskhasnotbeenpickedupbyaconsumerthread.

• Theconsumerthreads– mustnotpickuptasksuntilthereissomethingpresentinthe

shareddatastructure.– Individualconsumerthreadshouldpickuptasksoneatatime

Contention:– Betweenproducers– Betweenconsumers– Betweenproducersandconsumers

37

Page 38: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Producer-ConsumerUsingLockspthread_mutex_t task_queue_lock; int task_available; main() {

.... task_available = 0; pthread_mutex_init(&task_queue_lock, NULL); ....

}

38

void *producer(void *producer_thread_data) {....while (!done()) {

inserted = 0;create_task(&my_task);while (inserted == 0) {

pthread_mutex_lock(&task_queue_lock);if (task_available == 0) {

insert_into_queue(my_task);task_available = 1; inserted = 1;

}pthread_mutex_unlock(&task_queue_lock);

}}

}

void *consumer(void *consumer_thread_data) {int extracted; struct task my_task; while (!done()) {

extracted = 0;while (extracted == 0) {

pthread_mutex_lock(&task_queue_lock); if (task_available == 1) {

extract_from_queue(&my_task);task_available = 0; extracted = 1;

}pthread_mutex_unlock(&task_queue_lock);

}process_task(my_task);

} }

CriticalSection

Notethepurposeofinsertedandextraced variables

Page 39: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThreeTypesofMutexes

• Normal– Deadlocksifathreadalreadyhasalockandtriesasecondlockonit.

• Recursive– Allowsasinglethreadtolockamutex asmanytimesasitwants.

• Itsimplyincrementsacountonthenumberoflocks.– Alockisrelinquishedbyathreadwhenthecountbecomeszero.

• Errorcheck– Reportsanerrorwhenathreadwithalocktriestolockitagain(as

opposedtodeadlockinginthefirstcase,orgrantingthelock,asinthesecondcase).

• Thetypeofthemutex canbesetintheattributesobjectbeforeitispassedattimeofinitialization– pthread_mutex_attr_init

39

Page 40: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

OverheadsofLocking

40

• Locksenforceserialization– Threadmustexecutecriticalsectionsoneafteranother

• Largecriticalsectionscanleadtosignificantperformancedegradation.

• Reducetheblockingoverheadassociatedwithlocksusing:

int pthread_mutex_trylock (pthread_mutex_t *mutex_lock);

– acquirelockifavailable– returnEBUSYifnotavailable– enablesathreadtodosomethingelseiflockunavailable

• pthread trylock typicallymuchfasterthanlock oncertainsystems– Itdoesnothavetodealwithqueuesassociatedwithlocksformultiple

threadswaitingonthelock.

Page 41: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

41

ConditionVariablesforSynchronization

Aconditionvariable:associatedwithapredicate andamutex– Asyncvariableforacondition,e.g.mybalance >500

• Athreadcanblockitselfuntilaconditionbecomestrue– Whenblocked,releasemutex sootherscanacquireit

• Whenaconditionbecomestrue,observedbyanotherthread,theconditionvariableisusedtosignalotherthreadswhoareblocked

• Aconditionvariablealwayshasamutex associatedwithit.– Athreadlocksthismutex andteststhecondition

Page 42: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

42

ConditionVariablesforSynchronization/*theopaquedatastructure*/pthread_cond_t

/*initializationanddestroying*/int pthread_cond_init(pthread_cond_t *cond,

const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond);

/*blockandreleaselockuntilaconditionistrue*/int pthread_cond_wait(pthread_cond_t *cond,

pthread_mutex_t *mutex);int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *wtime);

/*signaloneorallwaitingthreadsthatconditionistrue*/int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond);

Page 43: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

pthread_cond_t cond_queue_empty, cond_queue_full; pthread_mutex_t task_queue_cond_lock; int task_available; /* other data structures here */

main() { /* declarations and initializations */ task_available = 0; pthread_cond_init(&cond_queue_empty, NULL); pthread_cond_init(&cond_queue_full, NULL); pthread_mutex_init(&task_queue_cond_lock, NULL); /* create and join producer and consumer threads */

}

43

Producer-ConsumerUsingConditionVariables

• Twoconditions:• Queueisfull:(task_available ==1)ß cond_queue_full• Queueisempty:(task_available ==0)ß cond_queue_empty

• Amutex forprotectingaccessingthequeue(CS):task_queue_cond_lock

Page 44: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

void *producer(void *producer_thread_data) { int inserted; while (!done()) {

create_task(); pthread_mutex_lock(&task_queue_cond_lock);

while (task_available == 1) pthread_cond_wait(&cond_queue_empty,

&task_queue_cond_lock);

insert_into_queue(); task_available = 1; CS

pthread_cond_signal(&cond_queue_full);

pthread_mutex_unlock(&task_queue_cond_lock); }

}

44

Producer-ConsumerUsingConditionVariables

Releasemutex (unlock)whenblocked/wait

Acquiremutex (lock)whenawaken

Producer:1. Waitforqueuetobecomeempty,notifiedbyconsumerthroughcond_queue_empty2. insertintoqueue3. Signalconsumerthroughcond_queue_full

1

2

3

Page 45: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

void *consumer(void *consumer_thread_data) { while (!done()) { pthread_mutex_lock(&task_queue_cond_lock);

while (task_available == 0) pthread_cond_wait(&cond_queue_full, &task_queue_cond_lock);

my_task = extract_from_queue(); task_available = 0;

pthread_cond_signal(&cond_queue_empty);

pthread_mutex_unlock(&task_queue_cond_lock); process_task(my_task);

} }

45

Consumer:1. Waitforqueuetobecomefull,notifiedbyproducerthroughcond_queue_full2. Extracttaskfromqueue3. Signalproducerthroughcond_queue_empty

Releasemutex (unlock)whenblocked/wait

Acquiremutex (lock)whenawaken

Producer-ConsumerUsingConditionVariables

1

2

3

Page 46: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

ThreadandSynchronizationAttributes

• Threemajorobjects– pthread_t– pthread_mutex_t– pthread_cond_t

• Defaultattributeswhenbeingcreated/initialized– NULL

• Anattributesobjectisadata-structurethatdescribesentity(thread,mutex,conditionvariable)properties.– Oncethesepropertiesareset,theattributesobjectcanbe

passedtothemethodinitializingtheentity.– Enhancesmodularity,readability,andeaseofmodification.

46

Page 47: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

AttributesObjectsforThreads

47

• Initializeanattributeobjectsusingpthread_attr_init

• Individualpropertiesassociatedwiththeattributesobjectcanbechangedusingthefollowingfunctions:pthread_attr_setdetachstate, pthread_attr_setguardsize_np, pthread_attr_setstacksize, pthread_attr_setinheritsched,pthread_attr_setschedpolicy, andpthread_attr_setschedparam

Page 48: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

AttributesObjectsforMutexes

48

• Initializeanattributesobjectusingfunction:pthread_mutexattr_init.

• pthread_mutexattr_settype_np forsettingthemutex typepthread_mutexattr_settype_np (pthread_mutexattr_t*attr,int type);

• Specifictypes:– PTHREAD_MUTEX_NORMAL_NP– PTHREAD_MUTEX_RECURSIVE_NP– PTHREAD_MUTEX_ERRORCHECK_NP

Page 49: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

AttributesObjectsforConditionVariable

• Initializeanattributeobjectusingpthread_condattr_init

• int pthread_condattr_setpshared(pthread_condattr_t*cattr,int pshared)tospecifiesthescopeofaconditionvariabletoeitherprocessprivate(intraprocess)orsystemwide(interprocess)viapshared– PTHREAD_PROCESS_SHARED– PTHREAD_PROCESS_PRIVATE

49

Page 50: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• PthreadMutex andConditionVariablesaretwobasicsyncoperations.

• Higherlevelconstructscanbebuiltusingbasicconstructs.– Read-writelocks– Barriers

• Pthread hasitscorrespondingimplementation– pthread_rwlock_t– pthread_barrier_t

• Wewilldiscussourownimplementations

50

CompositeSynchronizationConstructs

Page 51: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

51

Read-WriteLocks

• Concurrentaccesstodatastructure:– Readfrequentlybut– Writteninfrequently

• Behavior:– Concurrentread:Areadrequestisgrantedwhenthereare

otherreadsornowrite(pendingwriterequest).– Exclusivewrite:Awriterequestisgrantedonlyifthereisno

writeorpendingwriterequest,orreads.• Interfaces:

– Therw lockdatastructure:struct mylib_rwlock_t– Readlock:mylib_rwlock_rlock– writelock:mylib_rwlock_wlock– Unlock:mylib_rwlock_unlock.

Page 52: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

• Twotypesofmutualexclusions– 0/1mutex forprotectingaccesstowrite– Countermutex (semaphore)forcountingreadaccess

• Componentsketch– acountofthenumberofreaders,– 0/1integerspecifyingwhetherawriterispresent,– aconditionvariablereaders_proceed thatissignaledwhenreaders

canproceed,– aconditionvariablewriter_proceed thatissignaledwhenoneofthe

writerscanproceed,– acountpending_writers ofpendingwriters,and– apthread_mutex_t read_write_lock associatedwiththeshareddata

structure

52

Read-WriteLocks

Page 53: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

53

Read-WriteLockstypedef struct { int readers; int writer; pthread_cond_t readers_proceed; pthread_cond_t writer_proceed; int pending_writers; pthread_mutex_t read_write_lock;

} mylib_rwlock_t;

void mylib_rwlock_init (mylib_rwlock_t *l) { l->readers=0; l->writer=0; l->pending_writers=0; pthread_mutex_init(&(l->read_write_lock), NULL); pthread_cond_init(&(l->readers_proceed), NULL); pthread_cond_init(&(l->writer_proceed), NULL);

}

Page 54: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Read-WriteLocks

void mylib_rwlock_rlock(mylib_rwlock_t *l) { pthread_mutex_lock(&(l->read_write_lock));

while ((l->pending_writers > 0) || (l->writer > 0)) pthread_cond_wait(&(l->readers_proceed), &(l->read_write_lock));

l->readers ++;

pthread_mutex_unlock(&(l->read_write_lock)); }

54

Readerlock:1. ifthereisawriteorpendingwriters,performconditionwait,2. elseincrementcountofreadersandgrantreadlock

1

2

Page 55: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Read-WriteLocksvoid mylib_rwlock_wlock(mylib_rwlock_t *l) { pthread_mutex_lock(&(1->read_write_lock)); 1->pending_writers ++;

while ((1->writer > 0) || (1->readers > 0)) { pthread_cond_wait(&(1->writer_proceed),

&(1->read_write_lock));}

1->pending_writers --; 1->writer ++;

pthread_mutex_unlock(&(1->read_write_lock)); }

55

Writerlock:1. Iftherearereadersorwriters,incrementpendingwriters

countandwait.2. Onbeingwoken,decrementpendingwriterscountand

incrementwritercount

1

2

Page 56: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Read-WriteLocks

void mylib_rwlock_unlock(mylib_rwlock_t *l) { pthread_mutex_lock(&(1->read_write_lock)); if (1->writer > 0) /* only writer */1->writer = 0;

else if (1->readers > 0) /* only reader */1->readers --;

pthread_mutex_unlock(&(1->read_write_lock));

if ((1->readers == 0) && (1->pending_writers > 0)) pthread_cond_signal(&(1->writer_proceed));

else if (1->readers > 0) pthread_cond_broadcast(&(1->readers_proceed));

}

56

Reader/Writerunlock:1. Ifthereisawritelockthenunlock2. Iftherearereadlocks,decrementcountofreadlocks.3. Ifthereadcountbecomes0andthereisapendingwriter,notifywriter4. Otherwiseiftherearependingreaders,letthemallgothrough

1

2

3

4

Page 57: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Barrier

• Abarrierholdsoneormultiplethreadsuntilallthreadsparticipatinginthebarrierhavereachedthebarrierpoint

57

Page 58: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Barrier

• Needsacounter,amutex andaconditionvariable– Thecounterkeepstrackofthenumberofthreadsthathave

reachedthebarrier.• Ifthecountislessthanthetotalnumberofthreads,thethreadsexecuteaconditionwait.

– Thelastthreadentering(master)wakesupallthethreadsusingaconditionbroadcast.

58

typedef struct {int count;pthread_mutex_t count_lock;pthread_cond_t ok_to_proceed;

} mylib_barrier_t;

void mylib_barrier_init(mylib_barrier_t *b) {b->count = 0;pthread_mutex_init(&(b->count_lock), NULL);pthread_cond_init(&(b->ok_to_proceed), NULL);

}

Page 59: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Barriers

void mylib_barrier (mylib_barrier_t *b, int num_threads) {pthread_mutex_lock(&(b->count_lock));

b->count ++;if (b->count == num_threads) {

b->count = 0;pthread_cond_broadcast(&(b->ok_to_proceed));

} elsewhile (pthread_cond_wait(&(b->ok_to_proceed),&(b->count_lock)) != 0);

pthread_mutex_unlock(&(b->count_lock));}

59

Barrier1. Eachthreadincrementsthecounterandcheckwhetherallreach2. Thethread(master)whodetectthatallreachessignalotherstoproceed3. Ifnotallreach,thethreadwaits

1

2

3

Page 60: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Flat/Linearvs Tree/LogBarrier

60

• Linear/Flatbarrier.– O(n)fornthread– Asinglemastertocollectinformationofallthreadsandnotifythemto

continue• Tree/Logbarrier

– Organizethreadsinatreelogically– Multiplesubmaster tocollectandnotify– RuntimegrowsasO(logp).

Page 61: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

Barrier

• Executiontimeof1000sequentialandlogarithmicbarriersasafunctionofnumberofthreadsona32processorSGIOrigin2000.

61

Page 62: Lecture 08: Programming with PThreads: PThreadsbasics ... · –Thread basics and the POSIX Thread API ... – Set of pending and blocked signals – Thread specific data. •Multiple

References

• Adaptedfromslides“ProgrammingSharedAddressSpacePlatforms”byAnanth Grama.BradfordNichols,DickButtlar,JacquelineProulx Farrell.

• “Pthreads Programming:APOSIXStandardforBetterMultiprocessing.”O'ReillyMedia,1996.

• Chapter7.“IntroductiontoParallelComputing”byAnanthGrama,Anshul Gupta,GeorgeKarypis,andVipin Kumar.AddisonWesley,2003

• Otherpthread topics– int pthread_key_create(pthread_key_t *key,void(*destroy)(void*))– int pthread_setspecific(pthread_key_t key,const void*value)– void*pthread_getspecific(pthread_key_t key)

62