Basically, I need to complete some requirements. The first one was to compute this hierarchy.
The second one was based on synchronizing threads from the same process. This was the requirment:
Process P7 must create 5 threads: T7.1, T7.2, …, T7.5. You must impose on the execution of the process P7’s threads the following synchronization conditions:
• Process’ main thread, i.e. T7.0 must not terminate before the other 5 threads. This means that its “info(END, …)” message must not be called before the similar calls of the other threads. In terms of messages, its END message must never be displayed before any END message of the other threads.
• Thread T7.1 must start before T7.5 starts and terminate after T7.5 terminates.
I was able to do these two, but now I am stuck at third one, which is: synchronizing threads from different processes, I am asked the following: Process P3 must create 6 threads: T3.1, T3.2, …, T3.6. You must impose on the execution of the processes P3’s and P7’s threads the following synchronization conditions:
• Process’ main thread, i.e. T3.0 must not terminate before the other 6
threads.
• The thread T3.3 must terminate before T7.2 starts, but T3.4 must start
only after T7.2 terminates.
The “info()” function basically (at least from your point of view) displays a message. If we are at the beginning or end of a thread/process, the process number and the thread number.
I was trying to use the same logic and some help I found on this site, that is using ‘shared’ semaphores:
sem_t *semaphore = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (semaphore == MAP_FAILED || sem_init(semaphore, 1, 0) == -1) {
perror("Semaphore initialization failed");
exit(EXIT_FAILURE);
}
If I try to use this and delete the else{wait(NULL)} for processes 3,7 and 2, the process hierarchy is not good anymore. This is my code:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#include "a2_helper.h"
sem_t sem_thread1, sem_thread5;
sem_t sem_thread3_3, sem_thread7_2;
sem_t test, test1;
void *thread1(void *arg) {
int thread_num = ((int)arg);
info(BEGIN,7,thread_num);
sem_post(&sem_thread1);
sem_wait(&sem_thread5);
info(END,7,thread_num);
pthread_exit(NULL);
}
void *thread5(void *arg) {
int thread_num = ((int)arg);
sem_wait(&sem_thread1);
info(BEGIN,7,thread_num);
info(END,7,thread_num);
sem_post(&sem_thread5);
pthread_exit(NULL);
}
void *dummy_thread(void *arg) {
// Dummy thread function
int thread_num = ((int)arg);
info(BEGIN,7,thread_num);
info(END,7,thread_num);
pthread_exit(NULL);
}
void *dummy_thread2(void *arg) {
// Dummy thread function
int thread_num = ((int)arg);
info(BEGIN,3,thread_num);
info(END,3,thread_num);
pthread_exit(NULL);
}
int main() {
pthread_t threads[5];
//pthread_t threads2[50];
pthread_t threads3[50];
int thread_nums[50];
for(int i=0; i<50; i++){
thread_nums[i]=i+1;
}
// P1
init();
info(BEGIN, 1, 0);
// P2
if (fork() == 0) {
info(BEGIN, 2, 0);
// P5
if (fork() == 0) {
info(BEGIN, 5, 0);
// P8
if (fork() == 0) {
info(BEGIN, 8, 0);
info(END, 8, 0);
_exit(0);
} else {
wait(NULL);
}
info(END, 5, 0);
_exit(0);
} else {
wait(NULL);
}
//P3
if(fork()==0){
info(BEGIN,3,0);
// THREADS OF P3
pthread_create(&threads3[0], NULL, dummy_thread2, &thread_nums[0]);
pthread_create(&threads3[1], NULL, dummy_thread2, &thread_nums[1]);
pthread_create(&threads3[2], NULL, dummy_thread2, &thread_nums[2]);
pthread_create(&threads3[3], NULL, dummy_thread2, &thread_nums[3]);
pthread_create(&threads3[4], NULL, dummy_thread2, &thread_nums[4]);
pthread_create(&threads3[5], NULL, dummy_thread2, &thread_nums[5]);
pthread_join(threads3[0], NULL);
pthread_join(threads3[1], NULL);
pthread_join(threads3[2], NULL);
pthread_join(threads3[3], NULL);
pthread_join(threads3[4], NULL);
pthread_join(threads3[5], NULL);
// THREADS OF P3
info(END,3,0);
_exit(0);
}else{
wait(NULL);
}
info(END, 2, 0);
_exit(0);
} else {
wait(NULL);
}
// P4
if (fork() == 0) {
info(BEGIN, 4, 0);
// P6
if (fork() == 0) {
info(BEGIN, 6, 0);
info(END, 6, 0);
_exit(0);
} else {
wait(NULL);
}
info(END, 4, 0);
_exit(0);
} else {
wait(NULL);
}
//P7
if(fork()==0){
info(BEGIN,7,0);
sem_init(&sem_thread1, 0, 0);
sem_init(&sem_thread5, 0, 0);
// Create threads
pthread_create(&threads[0], NULL, thread1, &thread_nums[0]);
pthread_create(&threads[1], NULL, dummy_thread, &thread_nums[1]);
pthread_create(&threads[2], NULL, dummy_thread, &thread_nums[2]);
pthread_create(&threads[3], NULL, dummy_thread, &thread_nums[3]);
pthread_create(&threads[4], NULL, thread5, &thread_nums[4]);
// Join threads
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
pthread_join(threads[3], NULL);
pthread_join(threads[4], NULL);
info(END,7,0);
_exit(0);
}else{
wait(NULL);
}
sem_destroy(&sem_thread1);
sem_destroy(&sem_thread5);
info(END, 1, 0);
return 0;
}
Can I use the same logic to solve the problem or do I need another approach? I really suck at this, so please be patient with me haha. Thank you
Denis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.