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

Codes

The document discusses thread synchronization and producer-consumer problems. It presents code examples using threads, locks and conditions to safely share a fixed-size buffer between a producer adding data and a consumer removing data. The examples demonstrate how to prevent race conditions and ensure only one thread accesses the shared resource at a time.

Uploaded by

jhalili21
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Codes

The document discusses thread synchronization and producer-consumer problems. It presents code examples using threads, locks and conditions to safely share a fixed-size buffer between a producer adding data and a consumer removing data. The examples demonstrate how to prevent race conditions and ensure only one thread accesses the shared resource at a time.

Uploaded by

jhalili21
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 35

WEEK 1

printChar
// The task for printing a specified character in specified times
public class PrintChar implements Runnable {

private char charToPrint; // The character to print


private int times; // The times to repeat
private Thread prev; //a thread to join
/**
* Construct a task with specified character and number of times to print
* the character
*/
public PrintChar(char c, int t) {
charToPrint = c;
times = t;
prev = null;
}

public void waitFor(Thread t){


prev = t;
}

@Override
/**
* Override the run() method to tell the system what the task to perform
*/
public void run() {
System.out.print(Thread.currentThread().getName()+" started. ");
for (int i = 0; i < times; i++) {
System.out.print(" "+charToPrint);
if(i==70){
try {
if(prev != null) {
prev.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
printNum
// The task class for printing number from 1 to n for a given n
public class PrintNum implements Runnable {

private int lastNum;

/**
* Construct a task for printing 1, 2, ... i
*/
public PrintNum(int n) {
lastNum = n;
}

@Override
/**
* Tell the thread how to run
*/
public void run() {
System.out.print(Thread.currentThread().getName()+" started. ");
for (int i = 1; i <= lastNum; i++) {
System.out.print(" " + i);
}
}
}

Threadsexample6
/* The last discussed version of this example. Here we are again illustrating
the usage of the join method. In this case we are informing task printB to join
thread1 by calling a method that we added (waitFor).
*/
public class ThreadsExample6 {

public static void main(String[] args) throws InterruptedException {


// Create tasks
PrintChar printA = new PrintChar('a', 100);
PrintChar printB = new PrintChar('b', 100);
PrintNum print100 = new PrintNum(100);

// Create threads
Thread thread1 = new Thread(printA);
Thread thread2 = new Thread(printB);
Thread thread3 = new Thread(print100);

printB.waitFor(thread1);
// Start threads
thread1.start();
thread2.start();
thread3.start();

thread1.join();
thread2.join();
thread3.join();

System.out.print("MAIN-DONE");
}
}

producerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class ProducerConsumer {


private static Buffer buffer = new Buffer();

public static void main(String[] args) {


// Create a thread pool with two threads
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProducerTask());
executor.execute(new ConsumerTask());
executor.shutdown();
}

// A task for adding an int to the buffer


private static class ProducerTask implements Runnable {
public void run() {
try {
int i = 1;
while (true) {
System.out.println("Producer writes " + i);
buffer.write(i++); // Add a value to the buffer
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// A task for reading and deleting an int from the buffer


private static class ConsumerTask implements Runnable {
public void run() {
try {
while (true) {
System.out.println("\t\t\tConsumer reads " + buffer.read());
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// An inner class for buffer


private static class Buffer {
private static final int CAPACITY = 4; // buffer size
private java.util.LinkedList<Integer> queue =
new java.util.LinkedList<>();

// Create a new lock


private static Lock lock = new ReentrantLock();

// Create two conditions


private static Condition notEmpty = lock.newCondition();
private static Condition notFull = lock.newCondition();

public void write(int value) {


lock.lock(); // Acquire the lock
try {
while (queue.size() == CAPACITY) {
System.out.println("Wait for notFull condition");
notFull.await();
}

queue.offer(value);
notEmpty.signal(); // Signal notEmpty condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
}
}

public int read() {


int value = 0;
lock.lock(); // Acquire the lock
try {
while (queue.isEmpty()) {
System.out.println("\t\t\tWait for notEmpty condition");
notEmpty.await();
}

value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}

AccountswithSync

producerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class ProducerConsumer {


private static Buffer buffer = new Buffer();

public static void main(String[] args) {


// Create a thread pool with two threads
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProducerTask());
executor.execute(new ConsumerTask());
executor.shutdown();
}

// A task for adding an int to the buffer


private static class ProducerTask implements Runnable {
public void run() {
try {
int i = 1;
while (true) {
System.out.println("Producer writes " + i);
buffer.write(i++); // Add a value to the buffer
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// A task for reading and deleting an int from the buffer


private static class ConsumerTask implements Runnable {
public void run() {
try {
while (true) {
System.out.println("\t\t\tConsumer reads " + buffer.read());
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// An inner class for buffer


private static class Buffer {
private static final int CAPACITY = 4; // buffer size
private java.util.LinkedList<Integer> queue =
new java.util.LinkedList<>();

// Create a new lock


private static Lock lock = new ReentrantLock();

// Create two conditions


private static Condition notEmpty = lock.newCondition();
private static Condition notFull = lock.newCondition();

public void write(int value) {


lock.lock(); // Acquire the lock
try {
while (queue.size() == CAPACITY) {
System.out.println("Wait for notFull condition");
notFull.await();
}

queue.offer(value);
notEmpty.signal(); // Signal notEmpty condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
}
}

public int read() {


int value = 0;
lock.lock(); // Acquire the lock
try {
while (queue.isEmpty()) {
System.out.println("\t\t\tWait for notEmpty condition");
notEmpty.await();
}

value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}

AccountWithoutSynchronization
/**
* In this example is illustrated the unpleasant situation of "race condition"
* A large number of threads are created and they modify a simple instance of
* Account. As we are not taking care about synchronization, the final result
* may vary from one execution to another.
* The difference compared to the previous example is that ExecutorService is
* not used, but threads .
*/
public class AccountWithoutSynchronization {

private static Account account = new Account();

public static void main(String[] args) {


Thread threads[] = new Thread[100];

// Create 100 threads


for (int i = 0; i < 100; i++) {
threads[i] = new Thread(new AddAPennyTask());
}

// Start the 100 threads


for (int i = 0; i < 100; i++) {
threads[i].start();
}

for(int i=0; i < 100; i++){


try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println("What is balance? " + account.getBalance());


}

// A thread for adding a penny to the account


private static class AddAPennyTask implements Runnable{

public void run(){


account.deposit(1);
}
}

// An inner class for account


private static class Account {

private int balance = 0;

public int getBalance() {


return balance;
}

public void deposit(int amount) {


int newBalance = balance + amount;
//Thread.sleep(1); //to make the anomaly even more evident
balance = newBalance;
}
}
}

Countdown
/*
* In this fourth version of the program, two threads manipulate different countdown objects
* so no race conditions occur (as there is no common structure accessed by both threads).
* Each thread will continue counting on its own (however the precise order the in output is
* not predictable. You may try executing this several times and witness how the output may
vary.
* */
public class Main {
public static void main(String[] args) {
Countdown countdown = new Countdown(30);
Countdown countdown2 = new Countdown(30);

CountdownThread t1 = new CountdownThread(countdown);


t1.setName("Thread 1");
CountdownThread t2 = new CountdownThread(countdown2);
t2.setName("Thread 2");

t1.start();
t2.start();
}
}

class Countdown {
private int i;

public Countdown(int value) {


i = value;
}

public void doCountdown() {


String color;

switch (Thread.currentThread().getName()) {
case "Thread 1":
color = ThreadColors.ANSI_BLUE;
break;
case "Thread 2":
color = ThreadColors.ANSI_PURPLE;
break;
default:
color = ThreadColors.ANSI_GREEN;
}

while (i > 0) {
synchronized (this) {
System.out.println(color + Thread.currentThread().getName() + ": i =" + i);
i--;
}
try {
Thread.sleep((long)(50*Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}

class CountdownThread extends Thread {


private Countdown threadCountdown;

public CountdownThread(Countdown countdown) {


threadCountdown = countdown;
}

public void run() {


threadCountdown.doCountdown();
}
}

ThreadCooperation
/*
* In this example, two threads (DepositTask and WithdrawTask) modify
* together the balance of an account not only in a synchronized way,
* but also in cooperation. So the WithdrawTask will not withdraw if
* amount is larger than the current balance and DepositTask will wait
* if the amount would make the balance greater than 100.
*/
package Version1;

import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ThreadCooperationV3 {

private static Account account = new Account();


public final static String DepositColor = ThreadColors.ANSI_BLUE;
public final static String WithdrawColor = ThreadColors.ANSI_RED;

public static void main(String[] args) {


System.out.println("Thread 1\t\tThread 2\t\tBalance");
// Create a thread pool with two threads
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new DepositTask());
executor.execute(new WithdrawTask());
executor.shutdown();
}

public static class DepositTask implements Runnable {

@Override // Keep adding an amount to the account


public void run() {
try { // Purposely delay it to let the withdraw method proceed
while (true) {
account.deposit((int) (Math.random() * 50) + 1);
Thread.sleep(1000); //intentional delay to make it more visible
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

public static class WithdrawTask implements Runnable {

@Override // Keep subtracting an amount from the account


public void run() {
while (true) {
account.withdraw((int) (Math.random() * 20) + 1);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadCooperationV3.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
}

// An inner class for account


private static class Account {

// Create a new lock


private static Lock lock = new ReentrantLock();
// Create a condition
private static Condition newDeposit = lock.newCondition();
private static Condition newWithdraw = lock.newCondition();

private int balance = 0;


private int withdrawRequest;
private int depositRequest;

public int getBalance() {


return balance;
}

public void withdraw(int amount) {


lock.lock(); // Acquire the lock
try {
if (balance < amount) {
withdrawRequest = amount;
System.out.println(WithdrawColor + "\t\t\tWait for a deposit (cannot withdraw " +
amount + " )");
newDeposit.await();
}

balance -= amount;
if(balance + depositRequest <= 100){
newWithdraw.signalAll();
}

System.out.println(WithdrawColor + "\t\t\tWithdraw " + amount + "\t\t" + getBalance());


} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock(); // Release the lock
}
}

public void deposit(int amount) throws InterruptedException {


lock.lock(); // Acquire the lock
try {
if(balance + amount > 100){
depositRequest = amount;
System.out.println(DepositColor + "Cannot deposit " + amount + ". Waiting for
withdraw...");
newWithdraw.await();
}
balance += amount;
System.out.println(DepositColor + "Deposit " + amount + "\t\t\t\t\t" + getBalance());
if (balance >= withdrawRequest) {
newDeposit.signalAll();
}
} finally {
lock.unlock(); // Release the lock
}
}
}
}

ProducerConsumer
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer. When the buffer is full the ProducerTask
* has to wait and when the buffer is empty the ConsumerTask has to wait.
*/

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class ProducerConsumer {


private static Buffer buffer = new Buffer();

public static void main(String[] args) {


// Create a thread pool with two threads
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProducerTask());
executor.execute(new ConsumerTask());
executor.shutdown();
}

// A task for adding an int to the buffer


private static class ProducerTask implements Runnable {
public void run() {
try {
int i = 1;
while (true) {
System.out.println("Producer writes " + i);
buffer.write(i++); // Add a value to the buffer
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// A task for reading and deleting an int from the buffer


private static class ConsumerTask implements Runnable {
public void run() {
try {
while (true) {
System.out.println("\t\t\tConsumer reads " + buffer.read());
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 2000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// An inner class for buffer


private static class Buffer {
private static final int CAPACITY = 4; // buffer size
private java.util.LinkedList<Integer> queue =
new java.util.LinkedList<>();

// Create a new lock


private static Lock lock = new ReentrantLock();

// Create two conditions


private static Condition notEmpty = lock.newCondition();
private static Condition notFull = lock.newCondition();

public void write(int value) {


lock.lock(); // Acquire the lock
try {
while (queue.size() == CAPACITY) {
System.out.println("Wait for notFull condition");
notFull.await();
}
queue.offer(value);
notEmpty.signal(); // Signal notEmpty condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
}
}

public int read() {


int value = 0;
lock.lock(); // Acquire the lock
try {
while (queue.isEmpty()) {
System.out.println("\t\t\tWait for notEmpty condition");
notEmpty.await();
}

value = queue.remove();
notFull.signal(); // Signal notFull condition
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
finally {
lock.unlock(); // Release the lock
return value;
}
}
}
}

producerConsumerUsingBLOCKEDQUEUE
/*
* In this example two threads (ProducerTask and ConsumerTask) cooperate adding
* and removing data from a shared buffer which is implemented using blocking queues.
* If the buffer is full and the "put" method is called, then the current thread
* (ProducerTask) will have to wait.
* Alternatively, if the buffer is empty and the "take "method is called, then
* the current thread(ConsumerTask) will have to wait.
*/
import java.util.concurrent.*;

public class ProducerConsumerUsingBlockingQueue {


private static ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(3);

public static void main(String[] args) {


// Create a thread pool with two threads
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new ProducerTask());
executor.execute(new ConsumerTask());
executor.shutdown();
}

// A task for adding an int to the buffer


private static class ProducerTask implements Runnable {
public void run() {
try {
int i = 1;
while (true) {
System.out.println("Producer writes " + i);
buffer.put(i++); // Add any value to the buffer, say, 1
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 1000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}

// A task for reading and deleting an int from the buffer


private static class ConsumerTask implements Runnable {
public void run() {
try {
while (true) {
System.out.println("\t\t\tConsumer reads " + buffer.take());
// Put the thread into sleep
Thread.sleep((int)(Math.random() * 1000));
}
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}

BarrierExample
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this
license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package lab4examples;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class BarrierExample {

private static final int NUM_THREADS = 3;


private static final CyclicBarrier barrier = new CyclicBarrier(NUM_THREADS);

public static void main(String[] args) {


for (int i = 0; i < NUM_THREADS; i++) {
Thread thread = new Thread(new WorkerThread());
thread.start();
}
}

static class WorkerThread implements Runnable {


@Override
public void run() {
try {
// Stage 1: Initialize
System.out.println("Thread " + Thread.currentThread().getName() + " is initializing.");
Thread.sleep((long) (Math.random() * 2000));
System.out.println("Thread " + Thread.currentThread().getName() + " is ready for
stage 1.");
barrier.await(); // Wait for all threads to reach stage 1

// Stage 2: Process data


System.out.println("Thread " + Thread.currentThread().getName() + " is processing
data.");
Thread.sleep((long) (Math.random() * 2000));
System.out.println("Thread " + Thread.currentThread().getName() + " has finished
processing data.");
barrier.await(); // Wait for all threads to finish processing data

// Stage 3: Finalize
System.out.println("Thread " + Thread.currentThread().getName() + " is finalizing.");
Thread.sleep((long) (Math.random() * 2000));
System.out.println("Thread " + Thread.currentThread().getName() + " has finished
finalizing.");
barrier.await(); // Wait for all threads to finish finalizing
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("All done.");
}
}
}

SemaphoreTest
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javathreads;

import java.util.concurrent.Semaphore;

public class SemaphoreTest {

// max 4 people
static Semaphore semaphore = new Semaphore(4);

static class MyATMThread extends Thread {

String name = "";

MyATMThread(String name) {
this.name = name;
}

public void run() {

try {
System.out.println(name + " : acquiring lock...");
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());

semaphore.acquire();
System.out.println(name + " : got the permit!");

try {

for (int i = 1; i <= 5; i++) {

System.out.println(name + " : is performing operation " + i


+ ", available Semaphore permits : "
+ semaphore.availablePermits());

// sleep 1 second
Thread.sleep(1000);

} finally {

// calling release() after a successful acquire()


System.out.println(name + " : releasing lock...");
semaphore.release();
System.out.println(name + " : available Semaphore permits now: "
+ semaphore.availablePermits());

} catch (InterruptedException e) {

e.printStackTrace();

public static void main(String[] args) {

System.out.println("Total available Semaphore permits : "


+ semaphore.availablePermits());

MyATMThread t1 = new MyATMThread("A");


t1.start();

MyATMThread t2 = new MyATMThread("B");


t2.start();

MyATMThread t3 = new MyATMThread("C");


t3.start();

MyATMThread t4 = new MyATMThread("D");


t4.start();

MyATMThread t5 = new MyATMThread("E");


t5.start();

MyATMThread t6 = new MyATMThread("F");


t6.start();

}
}

CyclicBarrierExample
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* In this example the usage of cyclic barriers is demonstrated.
*/
public class CyclicBarrierExample {

private CyclicBarrier cyclicBarrier;


private List<List<Integer>> partialResults = Collections.synchronizedList(new ArrayList<>());
private Random random = new Random();
private int NUM_PARTIAL_RESULTS;
private int NUM_WORKERS;
class NumberCruncherThread implements Runnable {

@Override
public void run() {
String thisThreadName = Thread.currentThread().getName();
List<Integer> partialResult = new ArrayList<>();

// Crunch some numbers and store the partial result


for (int i = 0; i < NUM_PARTIAL_RESULTS; i++) {
Integer num = random.nextInt(10);
System.out.println(thisThreadName + ": Crunching some numbers! Current result - " +
num);
partialResult.add(num);
}

partialResults.add(partialResult);
try {
System.out.println(thisThreadName + " waiting for others to reach barrier (rendez-
vois).");
cyclicBarrier.await();
} catch (InterruptedException e) {
// ...
} catch (BrokenBarrierException e) {
// ...
}
System.out.println(thisThreadName + " finished waiting the barrier.");
}
}

class AggregatorThread implements Runnable {

@Override
public void run() {

String thisThreadName = Thread.currentThread().getName();

System.out.println(
thisThreadName + ": Computing sum of " + NUM_WORKERS
+ " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
int sum = 0;

for (List<Integer> threadResult : partialResults) {


System.out.print("Adding ");
for (Integer partialResult : threadResult) {
System.out.print(partialResult + " ");
sum += partialResult;
}
System.out.println();
}
System.out.println(thisThreadName + ": current result = " + sum);
}
}

public void runSimulation(int numWorkers, int numberOfPartialResults) {


NUM_WORKERS = numWorkers;
NUM_PARTIAL_RESULTS = numberOfPartialResults;

cyclicBarrier = new CyclicBarrier(NUM_WORKERS, new AggregatorThread());

System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute "


+ NUM_PARTIAL_RESULTS + " partial results each");

for (int i = 0; i < NUM_WORKERS; i++) {


Thread worker = new Thread(new NumberCruncherThread());
worker.setName("Thread " + i);
worker.start();
}
}

public static void main(String[] args) {


CyclicBarrierExample demo = new CyclicBarrierExample();
demo.runSimulation(5, 4);
}
}

—-------------------------POSIX THREADS—---------------------------------------
Pth_hello.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

const int MAX_THREADS = 64;

/* Global variable: accessible to all threads */


int thread_count;

void Usage(char* prog_name);


void *Hello(void* rank); /* Thread function */

/*--------------------------------------------------------------------*/
int main(int argc, char* argv[]) {
long thread; /* Use long in case of a 64-bit system */
pthread_t* thread_handles;

/* Get number of threads from command line */


if (argc != 2){
printf("Please enter the number of threads: ");
scanf("%d", &thread_count);
}else{
thread_count = strtol(argv[1], NULL, 10);
}

if (thread_count <= 0 || thread_count > MAX_THREADS){


Usage(argv[0]);
return -1;
}

thread_handles = malloc (thread_count*sizeof(pthread_t));

for (thread = 0; thread < thread_count; thread++)


pthread_create(&thread_handles[thread], NULL, Hello, (void*)thread);

printf("Hello from the main thread\n");

for (thread = 0; thread < thread_count; thread++)


pthread_join(thread_handles[thread], NULL);

free(thread_handles);
return 0;
} /* main */

/*-------------------------------------------------------------------*/
void *Hello(void* rank) {
long my_rank = (long) rank; /* Use long in case of 64-bit system */

printf("Hello from thread %ld of %d\n", my_rank, thread_count);

return NULL;
} /* Hello */
/*-------------------------------------------------------------------*/
void Usage(char* prog_name) {
fprintf(stderr, "usage: %s <number of threads>\n", prog_name);
fprintf(stderr, "0 < number of threads <= %d\n", MAX_THREADS);
exit(0);
} /* Usage */

pth_helloV2.c
//Threads in C

/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */

#define THREAD_NO 10

/* prototype for thread routine */


void print_message_function ( void *ptr );

/* struct to hold data to be passed to a thread


this shows how multiple data items can be passed to a thread */
typedef struct str_thdata
{
int thread_no;
char message[100];
} thdata;

int main()
{
pthread_t threads[THREAD_NO]; /* thread variables */
thdata data[THREAD_NO]; /* structs to be passed to threads */

/* initialize data to pass to thread 1 */


for(int i =0; i<THREAD_NO; i++){
data[i].thread_no = (i+1)*11;
if( i % 2 == 0){
strcpy(data[i].message, "Hello!");
}else{
strcpy(data[i].message, "Hi!");
}

}
/* create threads 1 and 2 */
for(int i =0; i<THREAD_NO; i++){
pthread_create (&threads[i], NULL, (void *) &print_message_function, (void *) &data[i]);
}

printf("Main thread says hello everyone! \n");

/* Main block now waits for both threads to terminate, before it exits
If main block exits, both threads exit, even if the threads have not
finished their work */
for(int i =0; i<THREAD_NO; i++){
pthread_join(threads[i], NULL);
}

/* exit */
exit(0);
} /* main() */

/**
* print_message_function is used as the start routine for the threads used
* it accepts a void pointer
**/
void print_message_function ( void *ptr )
{
thdata *data;
data = (thdata *) ptr; /* type cast to a pointer to thdata */

/* do the work */
printf("Thread %d says %s \n", data->thread_no, data->message);

pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */

Threads_printing.c
//Threads in C

/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */

/* prototype for thread routine */


void print_chars_function ( void *ptr );
void print_numbers_function ( void *ptr );

/* struct to hold data to be passed to a thread


this shows how multiple data items can be passed to a thread */
typedef struct str_thdata
{
char c;
int number;

} thdata;

int main()
{
pthread_t thread1, thread2, thread3; /* thread variables */
thdata data1, data2; /* structs to be passed to threads */

/* initialize data to pass to thread 1 */


data1.c = 'A';
data1.number = 20;

/* initialize data to pass to thread 2 */


data2.c = 'B';
data2.number = 20;

int number = 50;

/* create threads 1 and 2 */


pthread_create (&thread1, NULL, (void *) &print_chars_function, (void *) &data1);
pthread_create (&thread2, NULL, (void *) &print_chars_function, (void *) &data2);
pthread_create (&thread3, NULL, (void *) &print_numbers_function, (void *) &number);

/* Main block now waits for both threads to terminate, before it exits
If main block exits, both threads exit, even if the threads have not
finished their work */
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
/* exit */
exit(0);
} /* main() */

/**
* print_message_function is used as the start routine for the threads used
* it accepts a void pointer
**/
void print_chars_function ( void *ptr )
{
thdata *data;
data = (thdata *) ptr; /* type cast to a pointer to thdata */

/* do the work */
for(int i = 0; i<data->number; i++){
printf("%c\n", data->c);
if(i%5==0) sleep(1);
}

pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */

void print_numbers_function ( void *ptr )


{
int n = *((int *) ptr); /* type cast to a pointer to int */

/* do the work */
for(int i = 1; i<=n; i++){
printf("%d\n", i);
if(i % 20 == 0)
sleep(1);

pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */
AccountWithoutSync.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int balance = 0;

void deposit() {
int newbalance;
newbalance = balance + 1;
printf("The balance now is %d.\n",newbalance);
balance = newbalance;
//pthread_exit(0);
}

int main()
{
int i =0;
pthread_t threads[100];

for( i =0; i<100; i++){


pthread_create (&threads[i], NULL, (void *) &deposit, NULL);
}

for( i =0; i<100; i++){


pthread_join(threads[i], NULL);
}

printf("Balance at the end is: %d\n", balance );

exit(0);
}

AccountWithSync.c
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
int balance = 0;
pthread_mutex_t mutex;

void deposit() {
int newbalance;
pthread_mutex_lock(&mutex);
newbalance = balance + 1;
balance = newbalance;
printf("The balance now is %d.\n",newbalance);
pthread_mutex_unlock(&mutex);
}

int main()
{
int i =0;
pthread_t threads[100];

for( i =0; i<100; i++){


pthread_create (&threads[i], NULL, (void *) &deposit, NULL);
}

for( i =0; i<100; i++){


pthread_join(threads[i], NULL);
}

printf("Balance at the end is: %d\n", balance );

exit(0);
}

threadCooperation3.c
/*
* This example is a modification of the threadcooperation.c example.
* The DepositTask thread is allowed to make a deposit only if the new
* balance would not exceed the MAX_INSURANCE_LIMIT, otherwise it will
* wait for some withdrawals to be made.
* COMPARE THIS WITH THE SOLUTION IN JAVA
*/

#include <unistd.h> /* Symbolic Constants */


#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */

#define MAX_INSURANCE_LIMIT 100

void deposit();
void withdraw();
int balance=0;
pthread_mutex_t mutex;
pthread_cond_t cond_var, cond_var2;

int main()
{
pthread_t threads[2]; /* thread variables */
int i;
srand(time(NULL));

pthread_create (&threads[0], NULL, (void *) &deposit, NULL);


pthread_create (&threads[1], NULL, (void *) &withdraw, NULL);

for( i =0; i<2; i++){


pthread_join(threads[i], NULL);
}
printf("Balance is %d\n", balance);

exit(0);
} /* main() */

void deposit(){
while(1){
pthread_mutex_lock(&mutex);
int amount = rand()%40 +1;
while(balance+amount > MAX_INSURANCE_LIMIT){
printf("Cannot deposit %d, waiting ...\n",amount);
pthread_cond_wait(&cond_var2, &mutex);
}
int newBalance=balance+amount;
printf("Add %d. Balance now is %d\n",amount, newBalance);
balance=newBalance;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}

void withdraw(){
while(1) {
pthread_mutex_lock(&mutex);
int withdrawAmount = rand()%20 +1;
while(balance<withdrawAmount){
printf("\t\t\tCannot withdraw %d, waiting ...\n",withdrawAmount);
pthread_cond_wait(&cond_var, &mutex);
}
int newBalance = balance-withdrawAmount;
printf("\t\t\tWithdrew %d. Balance now is %d\n", withdrawAmount, newBalance);
balance = newBalance;
pthread_cond_broadcast(&cond_var2);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}

piEstimation.c
/*
* This example is a modification of the threadcooperation.c example.
* The DepositTask thread is allowed to make a deposit only if the new
* balance would not exceed the MAX_INSURANCE_LIMIT, otherwise it will
* wait for some withdrawals to be made.
* COMPARE THIS WITH THE SOLUTION IN JAVA
*/

#include <unistd.h> /* Symbolic Constants */


#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */

#define MAX_INSURANCE_LIMIT 100

void deposit();
void withdraw();
int balance=0;
pthread_mutex_t mutex;
pthread_cond_t cond_var, cond_var2;

int main()
{
pthread_t threads[2]; /* thread variables */
int i;
srand(time(NULL));

pthread_create (&threads[0], NULL, (void *) &deposit, NULL);


pthread_create (&threads[1], NULL, (void *) &withdraw, NULL);

for( i =0; i<2; i++){


pthread_join(threads[i], NULL);
}
printf("Balance is %d\n", balance);

exit(0);
} /* main() */

void deposit(){
while(1){
pthread_mutex_lock(&mutex);
int amount = rand()%40 +1;
while(balance+amount > MAX_INSURANCE_LIMIT){
printf("Cannot deposit %d, waiting ...\n",amount);
pthread_cond_wait(&cond_var2, &mutex);
}
int newBalance=balance+amount;
printf("Add %d. Balance now is %d\n",amount, newBalance);
balance=newBalance;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}

void withdraw(){
while(1) {
pthread_mutex_lock(&mutex);
int withdrawAmount = rand()%20 +1;
while(balance<withdrawAmount){
printf("\t\t\tCannot withdraw %d, waiting ...\n",withdrawAmount);
pthread_cond_wait(&cond_var, &mutex);
}
int newBalance = balance-withdrawAmount;
printf("\t\t\tWithdrew %d. Balance now is %d\n", withdrawAmount, newBalance);
balance = newBalance;
pthread_cond_broadcast(&cond_var2);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}

Timer.h
/* File: timer.h
*
* Purpose: Define a macro that returns the number of seconds that
* have elapsed since some point in the past. The timer
* should return times with microsecond accuracy.
*
* Note: The argument passed to the GET_TIME macro should be
* a double, *not* a pointer to a double.
*
* Example:
* #include "timer.h"
* ...
* double start, finish, elapsed;
* ...
* GET_TIME(start);
* ...
* Code to be timed
* ...
* GET_TIME(finish);
* elapsed = finish - start;
* printf("The code to be timed took %e seconds\n", elapsed);
*
* IPP: Section 3.6.1 (pp. 121 and ff.) and Section 6.1.2 (pp. 273 and ff.)
*/
#ifndef _TIMER_H_
#define _TIMER_H_

#include <sys/time.h>

/* The argument now should be a double (not a pointer to a double) */


#define GET_TIME(now) { \
struct timeval t; \
gettimeofday(&t, NULL); \
now = t.tv_sec + t.tv_usec/1000000.0; \
}

#endif

You might also like