Thread Creation Code

CPP(Thread class)


#include <thread>
#include <iostream>
void fun(int a){
    std::cout << "Hello";
}
int main() { 
    int a = 10;
    //Creates Thread Object, 
    //which is entity that can start 
    //execution immediately after creation
    std::thread t1(fun, a);
    t1.join();
    
    /* Not copy construtible */
    //error: use of deleted function 
    ‘std::thread::thread(std::thread&)’
    //std::thread t2 = t1
    
    /* Not copy assignable */
    //error: use of deleted function 
    //‘std::thread& std::thread::operator
    //=(const std::thread&)’
    //std::thread t2(fun,3);
    //t1 = t2;
}
                

- Thread calling method of class

#include<thread>
class A {
    void test(int a) {
        cout << a;
    }
public:
    void fun(int a) {
        //if we start thread on static function, 
        //then this will not be passed
        thread t1(&A::test, this, a);
        t1.join();
    }
};
int main() {
    A obj;
    obj.fun(1);
}
            

CPP(Functor)


#include <thread>
#include <iostream>
#include <mutex>
#include <vector>
std::mutex m;

void fun(int tid) {
    int a;
    m.lock();
    a += 5;
    std::cout << 
    "Thread: " << 
    tid << ", a:
    " << a << std::endl;
    m.unlock();
}

int main() {
    std::vector vecThreads;
    for (int i = 0; i< 5; ++i) {
        //Functor to create Threads
        vecThreads.emplace_back(
            [&]() {
                fun(i);
            }
        );
    }
    for (auto& t : vecThreads)
        t.join();
    return 0;
}

Rust

Creating Threads

1. std::thread::spawn
thread::spawn() takes a closure as an argument, which contains the code to be executed in the new thread
Normal Closure Scoped Threads(Borrow from env) Move Closure

$ cat main.rs
use std::thread;
fn fun1() {
    println!("Thread-1");
}

fn main() {
    let handle1 = thread::spawn(fun1);      //Thread-1

    let handle2 = thread::spawn(||{         //Thread-2
            println! ("Thread-2");
        });

    // Thread1, Thread2 are joinable.
    // main will not exit without t1,t2
    // spawn() returns Struct std::thread::JoinHandle 
    // which has method join() 
    handle1.join().unwrap();
    handle2.join().unwrap();
}
$ cargo run
                    
Normal Threads cannot borrow from their environment,
but scoped threads can

Scoped threads are not required to joined:
- Reason being, when scoped thread completes, its required
to return the borrowed data

fn main() {
    let a = 1;

    thread::scope(|scope| {
        scope.spawn(|| {
            println!("{}", a);
        });
    });
}
                    
The move keyword indicates that the closure
will take ownership of any variables it
captures from its environment.

use std::thread;

fn main() {
    let a = 10;
    let handle = thread::spawn(move || {
        println!("Thread {}", a);
    });

    handle.join().unwrap(); // Wait for the thread to finish
}
2. std::thread::Builder
Allows for more control over thread creation, such as setting stack size or naming the thread

use std::thread;

let builder = thread::Builder::new().name("my_thread".into()).stack_size(32 * 1024);
let handle = builder.spawn(|| {
    println!("Hello from a custom thread!");
}).unwrap();
handle.join().unwrap();
        
3. Asynchronous Frameworks (e.g., Tokio)
For asynchronous programming, you can use libraries like Tokio, which allows you to spawn tasks on a runtime.

#[tokio::main]
async fn main() {
    tokio::spawn(async {
        println!("Hello from an async task!");
    });
    // Other async code...
}
        

Python


import threading, zipfile

class AsyncZip(threading.Thread):
    def __init__(self, infile, outfile):              # Constructor
        threading.Thread.__init__(self)
        self.infile = infile
        self.outfile = outfile

    def run(self):
        f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
        f.write(self.infile)
        f.close()
        print('Finished background zip of:', self.infile)

background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')

background.join()    # Wait for the background task to finish
print('Main program waited until background was done.')
        

POSIX


#include <pthread.h>
#include <iostream>
using namespace std;
#define NUM_OF_THREADS 5

void* worker (void* arg) {
    
    cout << "Thread: " << *((int*)arg) << " Created" << endl;
}

int main() {
    pthread_t thread_id[NUM_OF_THREADS];
    int thread_args[NUM_OF_THREADS], ret;

    
    for (int i=0;i<NUM_OF_THREADS;++i) {
        thread_args[i] = i;
        ret = pthread_create(&thread_id[i], 0, worker, (void*)&thread_args[i]);
    }

    for (int i=0; i < NUM_OF_THREADS;++i)
        pthread_join (thread_id[i], 0);
    return 0;
}
        

Java


//Class should implement Runnable Interface to create Thread
class test implements Runnable {		
    test() {
        Thread cur = Thread.currentThread();

        //1. Created child thread
        Thread t = new Thread (this, "New thread");

        //2. Started child thread. 
        //if start() is not called, Child Thread will not start
        t.start();                                  
        try {
            for (int i = 0; i < 6; ++i) {
                //Parent process waits 1sec
                System.out.println ("Parent Thread");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println ("Interrupted");
        }
        System.out.println ("exiting main thread");
    }
    public void run () {
        try {
            for (int i = 0; i < 3; ++i) {
                //Child Thread waits 2sec
                System.out.println ("Child Thread");
                Thread.sleep(2000);
            }
        }
        catch (InterruptedException e) {
            System.out.println ("child interrupted");
        }
        System.out.println ("exiting child thread");
    }
    public static void main (String args[]) {
        new test();					//1. Calls constructor
    }
}
$ javac test.java
$ java test
$ java test
Parent Thread
Child Thread
Parent Thread
Child Thread
Parent Thread
Parent Thread
Child Thread
Parent Thread
Parent Thread
exiting child thread
exiting main thread
        

Windows


#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
using namespace std;
DWORD WINAPI worker(LPVOID param) {
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    int* data = (int*)param;
    TCHAR buf[60];
    DWORD dwChar;
    StringCchPrintf(buf, 60, TEXT("val=%d"), *data);
    WriteConsole(hStdout, buf, 10, &dwChar, nullptr);
    return 0;
}

int _tmain() {
    DWORD thread_id[5];
    for (int i = 0; i < 5; ++i) {
        CreateThread(
            NULL,               //Default security attributes
            0,                  //Use default stack size
            worker,             //thread function
            (void*)i,           //argument to thread function
            0,                  //Default creation flag
            &thread_id[i]);     //Thread identifier returned
    }
}