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

Lab 07 - Programming Threads

The document outlines a lab exercise for CS-330 Operating Systems focused on programming with threads using Pthreads. It provides an introduction to Pthreads, details on creating and managing threads, and includes sample code for implementing multi-threaded programs. The lab tasks require students to calculate the sum of integers using both single-threaded and multi-threaded approaches, with an emphasis on performance comparison and proper coding practices.

Uploaded by

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

Lab 07 - Programming Threads

The document outlines a lab exercise for CS-330 Operating Systems focused on programming with threads using Pthreads. It provides an introduction to Pthreads, details on creating and managing threads, and includes sample code for implementing multi-threaded programs. The lab tasks require students to calculate the sum of integers using both single-threaded and multi-threaded approaches, with an emphasis on performance comparison and proper coding practices.

Uploaded by

ahmadxaidi2004
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Faculty of Computing

CS-330 Operating System


BESE – 14AB
14th March 2025

Lab Engineer: Mr. Junaid Sajid


Instructor: Engr Taufeeq Ur Rehman

CS330: Operating Systems Page 1


Lab 07: Programming Threads
Introduction

The purpose of this lab is to learn threads programmatically.

Objectives

Objective of this lab is to enable students use threads in programs.

Tools/Software Requirement

Linux OS installed on laptops or systems.

Description

What are Pthreads?

1. POSIX Threads, or Pthreads, is a POSIX standard for threads. The standard, POSIX.1c,
Threads extensions (IEEE Std 1003.1c-1995), defines an API for creating and
manipulating threads.
2. Implementations of the API are available on many Unix-like POSIX systems such
as FreeBSD, NetBSD, GNU/Linux, Mac OS X and Solaris, but Microsoft
Windows implementations also exist. For example, the pthreads-w32 is available and
supports a subset of the Pthread API for the Windows 32-bit platform.
3. The POSIX standard has continued to evolve and undergo revisions, including the
Pthreads specification. The latest version is known as IEEE Std 1003.1, 2004 Edition.
4. Pthreads are defined as a set of C language programming types and procedure calls,
implemented with a pthread.h header file. In GNU/Linux, the pthread functions are not
included in the standard C library. They are in libpthrea, therefore, we should add -
lpthread to link our program.

The Pthread API

Pthreads API can be grouped into four:

1. Thread management:
Routines that work directly on threads - creating, detaching, joining, etc. They also include
functions to set/query thread attributes such as joinable, scheduling etc.
2. Mutexes:
Routines that deal with synchronization, called a "mutex", which is an abbreviation for "mutual

CS330: Operating Systems Page 2


exclusion". Mutex functions provide for creating, destroying, locking and unlocking mutexes.
These are supplemented by mutex attribute functions that set or modify attributes associated with
mutexes.
3. Condition variables:
Routines that address communications between threads that share a mutex. Based upon
programmer specified conditions. This group includes functions to create, destroy, wait and
signal based upon specified variable values. Functions to set/query condition variable attributes
are also included.
4. Synchronization:
Routines that manage read/write locks and barriers.

Creating Threads

1. Our main() program is a single, default thread. All other threads must be explicitly
created by the programmer.
2. pthread_create creates a new thread and makes it executable. This routine can be called
any number of times from anywhere within our code.
3. pthread_create (pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)
(void *), void *arg) arguments:
1. thread:
An identifier for the new thread returned by the subroutine. This is a pointer
to pthread_t structure. When a thread is created, an identifier is written to the
memory location to which this variable points. This identifier enables us to refer
to the thread.
2. attr:
An attribute object that may be used to set thread attributes. We can specify a
thread attributes object, or NULL for the default values.
3. start_routine:
The routine that the thread will execute once it is created.

void *(*start_routine)(void *)

We should pass the address of a function taking a pointer to void as a parameter


and the function will return a pointer to void. So, we can pass any type of single
argument and return a pointer to any type.

CS330: Operating Systems Page 3


4. arg:
A single argument that may be passed to start_routine. It must be passed as
a void pointer. NULL may be used if no argument is to be passed.
4. The maximum number of threads that may be created by a process is implementation
dependent.
5. Once created, threads are peers, and may create other threads. There is no implied
hierarchy or dependency between threads.
6. Here is a sample of creating a child thread:

// thread0.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

void *worker_thread(void *arg)


{
printf("This is worker_thread()\n");
pthread_exit(NULL);
}

int main()
{
pthread_t my_thread;
int ret;

printf("In main: creating thread\n");


ret = pthread_create(&my;_thread, NULL, &worker;_thread, NULL);
if(ret != 0) {
printf("Error: pthread_create() failed\n");
exit(EXIT_FAILURE);
}

pthread_exit(NULL);
}

In the code, the main thread will create a second thread to execute worker_thread(), which will
print out its message while main thread prints another. The call to create the thread has a NULL
value for the attributes, which gives the thread default attributes. The call also passes the address
of a my_thread variable for the worker_thread() to store a handle to the thread. The return
value from the pthread_create() call will be zero if it's successful, otherwise, it returns an error.

Compile and run:

CS330: Operating Systems Page 4


$ gcc -o thread0 thread0.c –lpthread
$ ./thread0

Output:

In main: creating thread


This is worker_thread()

We can create several child threads:

// thread01.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define N 5

void *worker_thread(void *arg)


{
printf("This is worker_thread #%ld\n", (long)arg);
pthread_exit(NULL);
}

int main()
{
pthread_t my_thread[N];

long id;
for(id = 1; id <= N; id++) {
int ret = pthread_create(&my;_thread[id], NULL, &worker;_thread, (void*)id);
if(ret != 0) {
printf("Error: pthread_create() failed\n");
exit(EXIT_FAILURE);
}
}

pthread_exit(NULL);
}

Compile and run:

$ gcc -o thread01 thread01.c –lpthread


$ ./thread01

CS330: Operating Systems Page 5


Output:

This is worker_thread #5
This is worker_thread #4
This is worker_thread #3
This is worker_thread #2
This is worker_thread #1

Note that, in the code, we pass the parameter (thread id) to the child thread.

If we do (void*)&id, it's a wrong way of passing data to the child thread. It passes the address of
variable id, which is shared memory space and visible to all threads. As the loop iterates, the
value of this memory location changes, possibly before the created threads can access it.

Attributes of Threads

1. By default, a thread is created with certain attributes. Some of these attributes can be
changed by the programmer via the thread attribute object.
2. pthread_attr_init() and pthread_attr_destroy() are used to initialize/destroy the thread
attribute object.
3. Other routines are then used to query/set specific attributes in the thread attribute object.

Terminating Threads

1. There are several ways in which a Pthread may be terminated:


1. The thread returns from its starting routine (the main routine for the initial thread).
2. The thread makes a call to the pthread_exit subroutine.
3. The thread is canceled by another thread via the pthread_cancel routine
4. The entire process is terminated due to a call to either the exec or exit subroutines.
2. pthread_exit is used to explicitly exit a thread. Typically, the pthread_exit() routine is
called after a thread has completed its work and is no longer required to exist.
If main() finishes before the threads it has created, and exits with pthread_exit(), the
other threads will continue to execute. Otherwise, they will be automatically terminated

CS330: Operating Systems Page 6


when main() finishes.
So, if we comment out the line pthread_exit() in main() in the thread01.c of the
previous example code, the threads created may not have a chance to execute their work
before being terminated.
3. The programmer may optionally specify a termination status, which is stored as a void
pointer for any thread that may join the calling thread.
4. Cleanup: the pthread_exit() routine does not close files; any files opened inside the
thread will remain open after the thread is terminated.

Join

1. int pthread_join (pthread_t th, void **thread_return)


The first parameter is the thread for which to wait, the identified
that pthread_create filled in for us. The second argument is a pointer to a pointer that
itself points to the return value from the thread. This function returns zero for success and
an error code on failure.
2. When a thread is created, one of its attributes defines whether the thread is joinable or
detached. Only threads that are created as joinable can be joined. If a thread is created as
detached, it can never be joined.
3. The final draft of the POSIX standard specifies that threads should be created as joinable.

Picture from https://computing.llnl.gov/tutorials/pthreads/

A thread can execute a thread join to wait until the other thread terminates. In our case, you - the
main thread - should execute a thread join waiting for your colleague - a child thread - to

CS330: Operating Systems Page 7


terminate. In general, thread join is for a parent (P) to join with one of its child threads (C).
Thread join has the following activities, assuming that a parent thread P wants to join with one of
its child threads C:

1. When P executes a thread join in order to join with C, which is still running, P is
suspended until C terminates. Once C terminates, P resumes.
2. When P executes a thread join and C has already terminated, P continues as if no such
thread join has ever executed (i.e., join has no effect).

A parent thread may join with many child threads created by the parent. Or, a parent only join
with some of its child threads, and ignore other child threads. In this case, those child threads that
are ignored by the parent will be terminated when the parent terminates.

1. The pthread_join() subroutine blocks the calling thread until the specified thread
terminates.
2. The programmer is able to obtain the target thread's termination return status if it was
specified in the target thread's call to pthread_exit() as show here:

void *worker_thread(void *arg)


{
pthread_exit((void*)911);
}

int main()
{
int i;
pthread_t thread;
pthread_create(&thread;, NULL, worker_thread, NULL);
pthread_join(thread, (void **)&i);
printf("%d\n",i); // will print out 911
}

3. A joining thread can match one pthread_join() call. It is a logical error to attempt
multiple joins on the same thread.

Tasks

1. Implement a simple program using for loop to calculate the sum of first 100 million positive
integers (i.e., 100,000,000) elements in an array.

CS330: Operating Systems Page 8


2. Convert the above code into multi-threaded program using pthreads library, which runs 4
threads in parallel.

3. Run the above code several time to verify that the threads runs concurrently and threads
execution varies in each run.

4. Use the code in task 1 and 2 to print the time each program takes to execute. Which program
runs faster and why?

Deliverables

Submit the document containing code and screenshot for of your programs, along with the
answer to the last question. You are supposed to strictly follow submission guidelines.

References:

 https://www.cs.cmu.edu/afs/cs/academic/class/15492-f07/www/pthreads.html
 https://www.includehelp.com/c/sum-of-an-array-using-multithreading-in-c-cpp.aspx

CS330: Operating Systems Page 9

You might also like