Skip to content

Lab4 - Thread

ตัวอย่างถัดไปแสดงการทำงานแยกกันของ Thread กับ main Process

Thread 1 ตัว

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void * thread_function(void * arg);
int i, j;
int main() {
pthread_t a_thread; //thread declaration
pthread_create( & a_thread, NULL, thread_function, NULL);
//thread is created
pthread_join(a_thread, NULL); //process waits for thread to finish . //Comment this line to see the difference
printf("Inside Main Program\n");
for (j = 20; j < 25; j++) {
printf("%d\n", j);
sleep(1);
}
}
void * thread_function(void * arg) {
// the work to be done by the thread is defined in this function
printf("Inside Thread\n");
for (i = 0; i < 5; i++) {
printf("%d\n", i);
sleep(1);
}
}

OUTPUT

Terminal window
0
1
2
3
4
Inside Main Program
20
21
22
23
24

ตัวอย่าง 2

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void * thread_function(void * arg);
int i, j;
int main() {
pthread_t a_thread; //thread declaration
pthread_create( & a_thread, NULL, thread_function, NULL);
//thread is created
printf("Inside Main Program\n");
for (j = 50; j < 60; j++) {
printf("Main %d\n", j);
sleep(1);
}
printf("Main thread end\n");
pthread_join(a_thread, NULL); //process waits for thread to finish . //Comment this line to see the difference
printf("Thread end\n");
}
void * thread_function(void * arg) {
// the work to be done by the thread is defined in this function
printf("Inside Thread\n");
for (i = 0; i < 50; i++) {
printf("Thread %d\n", i);
sleep(1);
}
}

ตัวอย่างถ้าไม่ join thread

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void * thread_function(void * arg);
int i, j;
int main() {
pthread_t a_thread; //thread declaration
pthread_create( & a_thread, NULL, thread_function, NULL);
//thread is created
printf("Inside Main Program\n");
for (j = 50; j < 60; j++) {
printf("Main %d\n", j);
sleep(1);
}
printf("Main thread end\n");
// pthread_join(a_thread, NULL); //process waits for thread to finish . //Comment this line to see the difference
printf("Thread end\n");
}
void * thread_function(void * arg) {
// the work to be done by the thread is defined in this function
printf("Inside Thread\n");
for (i = 0; i < 50; i++) {
printf("Thread %d\n", i);
sleep(1);
}
}

Thread 2 ตัว

#include <stdio.h>
#include <stdlib.h> // for srand(), rand()
#include <unistd.h> // for sleep(), usleep()
#include <pthread.h> // the header file for the pthread library
void *thread_entry_func( void *arg ) {
long id = (long)arg;
printf( "Thread '%ld' started\n", id );
// sleep for some seconds (randomized between 1..10)
sleep( 1 + (rand() % 10) );
printf( "Thread '%ld' finished\n", id );
return NULL;
}
int main( int argc, char *argv[] ) {
int retval; // return value from a function call
pthread_t thread1, thread2; // thread handles
// initialize the pseudo-random generator with a seed
srand( time(NULL) );
// create Thread 1
retval = pthread_create(
&thread1 /* used to identify thread 1 */,
NULL /* default attributes */,
thread_entry_func /* start routine */,
(void*) 1 /* thread argument \*/ );
printf( "Thread creation (1): %s\n", retval ? "FAILED" : "OK" );
// create Thread 2
retval = pthread_create(
&thread2 /* used to identify thread 2 */,
NULL /* default attributes */,
thread_entry_func /* start routine */,
(void*) 2 /* thread argument */ );
printf( "Thread creation (2): %s\n", retval ? "FAILED" : "OK" );
// sleep for 10msec
usleep( 10000 /*usec\*/ );
// wait until both threads (thread 1 and 2) are finished.
printf( "\nWaiting for threads to be finished...\n" );
if ( thread1 ) {
pthread_join( thread1, NULL ); // wait for thread 1
}
if ( thread2 ) {
pthread_join( thread2, NULL ); // wait for thread 2
}
printf( "Done...\n\n" );
return 0;
}

OUTPUT

Terminal window
Thread creation (1): OK
Thread '1' started
Thread creation (2): OK
Thread '2' started
Waiting for threads to be finished...
Thread '1' finished
Thread '2' finished
Done...

จะใช้การสร้าง Thread เก็บไว้ใน Array

#include <stdio.h>
#include <stdlib.h> // for srand(), rand()
#include <unistd.h> // for sleep(), usleep()
#include <pthread.h> // the header file for the pthread lib
#define NUM_THREADS (10)
void *thread_entry_func( void *arg ) {
long id = (long)arg;
printf( "Thread '%ld' started (0x%08lX)\n", id, pthread_self() );
// sleep for some seconds (randomized between 1..10)
sleep( 1 + (rand() % 10) );
printf( "Thread '%ld' finished\n", id );
return NULL;
}
int main( int argc, char *argv[] ) {
int retval;
pthread_t threads[ NUM_THREADS ]; // array of thread handles
// initialize the pseudorandom generator with a seed
srand( time(NULL) );
// create a number of threads
for ( int i=0; i < NUM_THREADS; i++ ) {
long id = (i+1); // used as thread argument
retval = pthread_create(
&threads[i], NULL,
thread_entry_func,
(void*) id );
printf( "main> thread creation (%ld): %s\n", id,
retval ? "FAILED" : "OK" );
if ( retval ) { // thread creation error
printf( "Program terminated...\n" );
exit(1);
}
}
// sleep for 1msec before proceeding
usleep( 1000 /*usec*/ );
// wait until all threads are finished.
printf( "\nWaiting for all threads to be finished..\n" );
for ( int i=0; i < NUM_THREADS; i++ ) {
pthread_join( threads[i], NULL ); // wait for thread
}
printf( "Done...\n\n" );
return 0;
}

OUTPUT

Terminal window
main> thread creation (1): OK
Thread '1' started (0x7FE7F8F41700)
main> thread creation (2): OK
Thread '2' started (0x7FE7F8740700)
main> thread creation (3): OK
Thread '3' started (0x7FE7F7F3F700)
main> thread creation (4): OK
Thread '4' started (0x7FE7F773E700)
main> thread creation (5): OK
Thread '5' started (0x7FE7F6F3D700)
main> thread creation (6): OK
Thread '6' started (0x7FE7F673C700)
main> thread creation (7): OK
Thread '7' started (0x7FE7F5F3B700)
main> thread creation (8): OK
Thread '8' started (0x7FE7F573A700)
main> thread creation (9): OK
Thread '9' started (0x7FE7F4F39700)
main> thread creation (10): OK
Thread '10' started (0x7FE7F4738700)
Waiting for all threads to be finished..
Thread '10' finished
Thread '3' finished
Thread '4' finished
Thread '6' finished
Thread '2' finished
Thread '5' finished
Thread '7' finished
Thread '9' finished
Thread '8' finished
Thread '1' finished
Done...

Thread คืนค่าไปให้ main Process

Section titled “Thread คืนค่าไปให้ main Process”

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
void * thread_function(void * arg);
int i, n, j;
int main() {
char * m = "5";
pthread_t a_thread; //thread declaration
void * result;
pthread_create( & a_thread, NULL, thread_function, m); //thread is created
pthread_join(a_thread, & result);
printf("Thread joined\n");
for (j = 20; j < 25; j++) {
printf("%d\n", j);
sleep(1);
}
printf("thread returned %s\n", (char * ) result);
}
void * thread_function(void * arg) {
int sum = 0;
n = atoi(arg);
for (i = 0; i < n; i++) {
printf("%d\n", i);
sleep(1);
}
pthread_exit("Done"); // Thread returns "Done"
}

OUTPUT

Terminal window
0
1
2
3
4
Thread joined
20
21
22
23
24
thread returned Done

#include<stdio.h>
#include<pthread.h>
struct arg_struct { //structure which contains multiple variables that are to passed as input to the thread
int arg1;
int arg2;
};
void * arguments(void * arguments) {
struct arg_struct * args = arguments;
printf("%d\n", args -> arg1);
printf("%d\n", args -> arg2);
pthread_exit(NULL);
}
int main() {
pthread_t t;
struct arg_struct args;
args.arg1 = 5;
args.arg2 = 7;
pthread_create( & t, NULL, arguments, & args);
//structure passed as 4th argument
pthread_join(t, NULL); /* Wait until thread is finished */
}

OUTPUT

Terminal window
5
7
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
// GLOBAL VARIABLES - SHARED between all threads
int global_counter = 0;
char global_message[100] = "Shared message";
void* thread_function(void* arg) {
int thread_id = *(int*)arg;
// LOCAL VARIABLES - PRIVATE to each thread (each thread has its own copy)
int local_counter = 0;
char local_message[50];
sprintf(local_message, "Thread %d private message", thread_id);
printf("Thread %d starting\n", thread_id);
for(int i = 0; i < 5; i++) {
// Each thread increments its own local counter
local_counter++;
// All threads share and modify the same global counter
global_counter++;
printf("Thread %d: local_counter=%d, global_counter=%d\n",
thread_id, local_counter, global_counter);
printf("Thread %d: local_message='%s'\n", thread_id, local_message);
printf("Thread %d: global_message='%s'\n", thread_id, global_message);
// sleep(1);
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
int id1 = 1, id2 = 2;
printf("=== VARIABLE SHARING DEMONSTRATION ===\n");
printf("Initial global_counter: %d\n", global_counter);
printf("Initial global_message: '%s'\n\n", global_message);
// Create two threads
pthread_create(&thread1, NULL, thread_function, &id1);
pthread_create(&thread2, NULL, thread_function, &id2);
// Let threads run for a bit, then modify global variable from main
sleep(3);
strcpy(global_message, "Modified by main thread");
printf("\n*** MAIN: Changed global_message ***\n\n");
// Wait for threads to complete
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("\nFinal global_counter: %d\n", global_counter);
printf("Final global_message: '%s'\n", global_message);
return 0;
}
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler(int sig) {
printf("Process %d received signal %d\n", getpid(), sig);
exit(0);
}
int main() {
printf("Press CTRL + C to send interrupt.\n");
sleep(1);
signal(SIGINT, signal_handler); // Register handler
while(1) {
// Process work - can be interrupted by signal
sleep(1);
}
}

OUTPUT

Terminal window
c@c:~/cos3105$ ./process_signals
Press CTRL + C to send interrupt.
^CProcess 2577 received signal 2
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
volatile int shutdown_flag = 0; // Global flag for coordinated shutdown
void signal_handler(int sig) {
printf("Process %d received signal %d\n", getpid(), sig);
if (sig == SIGINT || sig == SIGTERM) {
printf("Termination signal received, shutting down all threads\n");
shutdown_flag = 1; // Signal all threads to stop
exit(0); // Immediate shutdown for this example
}
}
// Designate one thread for signal handling
void* signal_thread(void* arg) {
sigset_t set;
int sig;
sigfillset(&set);
while(!shutdown_flag) {
if (sigwait(&set, &sig) == 0) { // Wait for signals
signal_handler(sig);
}
}
printf("Signal thread exiting\n");
return NULL;
}
// Worker thread function
void* worker_func(void* arg) {
while(!shutdown_flag) { // Check shutdown flag
printf("Worker thread working...\n");
sleep(1);
}
printf("Worker thread exiting gracefully\n");
return NULL;
}
int main() {
pthread_t sig_thread;
pthread_t worker;
// Block signals in all threads
sigset_t set;
sigfillset(&set);
pthread_sigmask(SIG_BLOCK, &set, NULL);
printf("Starting program. Use 'kill -2 %d' to send SIGINT\n", getpid());
// Create dedicated signal handler thread
pthread_create(&sig_thread, NULL, signal_thread, NULL);
// Create worker thread (signals blocked)
pthread_create(&worker, NULL, worker_func, NULL);
// Wait for threads to complete
pthread_join(sig_thread, NULL);
pthread_join(worker, NULL);
printf("Program terminated\n");
return 0;
}

OUTPUT

Terminal window
c@c:~/cos3105$ ./threads_signals
Starting program. Use 'kill -2 6193' to send SIGINT
Worker thread working...
Worker thread working...
Worker thread working...
Process 6193 received signal 2
Termination signal received, shutting down all threads