$29
For Windows system, I recommend you to install WSL. https://learn.microsoft.com/en-us/windows/wsl/install
In case of using Linux system, you need to link with pthread library using -l pthread during compile phase. Otherwise, you will fail to compile the source code. As an example, you should change your compile command from gcc q1.c -o q1 to gcc q1.c -l pthread -o q1.
Eclipse or other IDE would automatically assemble this library during compiling phase so you don’t have to explicitly do so.
In this section, students are required to execute the following codes, and try to understand the behaviour. For each program, students should capture a screenshot of the successful execution, and answer attached questions briefly. In the submission file, please attach the execution screenshot and the explanation of each question in sequence.
Q1: Execute the following code, and state why two PIDs are the same and why two threadIDs are different.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void kidfunc() {
printf("Kid PID is %d, thread ID is %d\n", getpid(), pthread_self());
}
int main() {
pthread_t kid;
pthread_create(&kid, NULL, kidfunc, NULL);
printf("Parent PID is %d, thread ID is %d\n", getpid(), pthread_self());
pthread_join(kid, NULL);
printf("Complete!\n");
return 0;
}
Q2: Execute the following code, and state if the global data in the last output is deterministic or not and why.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int glob_data = 5;
void* kidfunc() {
glob_data = 15;
}
int main() {
pthread_t kid;
printf("Start of program. Global data = %d.\n", glob_data);
pthread_create(&kid, NULL, kidfunc, NULL);
glob_data = 10;
pthread_join(kid, NULL);
printf("End of program. Global data = %d.\n", glob_data);
return 0;
}
Q3: Execute the following code, and state 1) why the variable this_is_global equals to 1002 in thread test, 2) Identify whether the address of variables in two threads are identical in thread test and why 3) why the modification occurred in child process doesn’t influence the value in parent process, 4) why the address of variables in two processes are identical in process test.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
int this_is_global;
void thread_func(void *dummy) {
int local_thread;
printf("Thread %d, pid %d, addresses: &this_is_global: %X, &local: %X\n",
pthread_self(), getpid(), &this_is_global, &local_thread);
this_is_global++;
printf("In Thread %d, incremented this_is_global=%d\n", pthread_self(),
this_is_global);
pthread_exit(0);
}
int main() {
// thread test
pthread_t thread1, thread2;
printf("First, we create two threads to see better what context they share...\n");
this_is_global = 1000;
printf("Set this_is_global=%d\n", this_is_global);
pthread_create(&thread1, NULL, (void*) &thread_func, (void*) NULL);
pthread_create(&thread2, NULL, (void*) &thread_func, (void*) NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("After threads, this_is_global=%d\n", this_is_global);
printf("\n");
printf("After testing threads, let's call fork..\n");
// process test
int local_main = 17;
this_is_global = 17;
printf("Before fork(), local_main=%d, this_is_global=%d\n", local_main, this_is_global);
fflush(stdout);
int pid = fork();
if (pid == 0) {
printf("In child, pid %d: &this_is_global: %X, &local_main: %X\n", getpid(), &this_is_global, &local_main);
local_main = 13;
this_is_global = 23;
printf("In child, local main=%d, this_is_global=%d\n", local_main, this_is_global);
exit(0);
} else {
printf("In parent, pid %d: &this_is_global: %X, &local_main: %X\n", getpid(), &this_is_global, &local_main);
wait(NULL);
printf("In parent, local_main=%d, this_is_global=%d\n", local_main, this_is_global);
exit(0);
}
}
Q4: Execute the following code multiple times and state why the result is not deterministic.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int tot_items = 0;
struct kidrec {
int data;
pthread_t id;
};
#define NKIDS 10
void* kidfunc(void *p) {
int *ip = (int*) p;
int tmp, n;
tmp = tot_items;
for (n = 500000; n--;)
tot_items = tmp + *ip;
}
int main() {
struct kidrec kids[NKIDS];
for (int m = 0; m < NKIDS; ++m) {
kids[m].data = m + 1;
pthread_create(&kids[m].id, NULL, kidfunc, &kids[m].data);
}
for (int m = 0; m < NKIDS; ++m)
pthread_join(kids[m].id, NULL);
printf("End of Program. Grand Total = %d\n", tot_items);
return 0;
}