Skip to content

Commit a245043

Browse files
committed
Create 5
1 parent 66d309b commit a245043

6 files changed

Lines changed: 569 additions & 0 deletions

File tree

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files.associations": {
3+
"unistd.h": "c",
4+
"errno.h": "c"
5+
}
6+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// consumer.c
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <fcntl.h>
6+
#include <sys/mman.h>
7+
#include <sys/stat.h>
8+
#include <semaphore.h>
9+
#include <time.h>
10+
#include <string.h>
11+
#include <float.h> // For FLT_MAX, FLT_MIN (or DBL_MAX etc.)
12+
#include <signal.h> // For signal handling
13+
14+
#include "data_structures.h" // Common header
15+
16+
SharedData *shared_data_ptr = NULL;
17+
int shm_fd = -1;
18+
sem_t *mutex_sem = SEM_FAILED;
19+
volatile sig_atomic_t keep_running = 1;
20+
21+
void cleanup_ipc_consumer() {
22+
printf("\nConsumer cleaning up...\n");
23+
if (shared_data_ptr != MAP_FAILED && shared_data_ptr != NULL) {
24+
if (munmap(shared_data_ptr, sizeof(SharedData)) == -1) {
25+
perror("munmap");
26+
}
27+
}
28+
if (shm_fd != -1) {
29+
close(shm_fd);
30+
// Consumer does NOT unlink shared memory, producer owns it
31+
}
32+
if (mutex_sem != SEM_FAILED) {
33+
sem_close(mutex_sem);
34+
// Consumer does NOT unlink semaphore, producer owns it
35+
}
36+
printf("Consumer cleanup complete.\n");
37+
}
38+
39+
void sigint_handler_consumer(int sig) {
40+
printf("\nConsumer received SIGINT. Shutting down...\n");
41+
keep_running = 0;
42+
}
43+
44+
int main() {
45+
struct sigaction sa;
46+
sa.sa_handler = sigint_handler_consumer;
47+
sigemptyset(&sa.sa_mask);
48+
sa.sa_flags = 0;
49+
if (sigaction(SIGINT, &sa, NULL) == -1) {
50+
perror("sigaction");
51+
return EXIT_FAILURE;
52+
}
53+
if (sigaction(SIGTERM, &sa, NULL) == -1) {
54+
perror("sigaction for SIGTERM");
55+
return EXIT_FAILURE;
56+
}
57+
58+
// 1. Open existing POSIX shared memory object (DO NOT CREATE)
59+
shm_fd = shm_open(SHM_NAME, O_RDWR, 0666); // O_RDONLY if only reading
60+
if (shm_fd == -1) {
61+
perror("shm_open (Is the producer.c program running?)");
62+
return EXIT_FAILURE;
63+
}
64+
65+
// 2. Map the shared memory object into the process's address space
66+
// Note: Size is known from SharedData struct. ftruncate is not needed here.
67+
shared_data_ptr = mmap(0, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); // PROT_READ if only reading
68+
if (shared_data_ptr == MAP_FAILED) {
69+
perror("mmap");
70+
close(shm_fd);
71+
return EXIT_FAILURE;
72+
}
73+
printf("Shared memory opened and mapped successfully.\n");
74+
75+
// 3. Open existing POSIX named semaphore (DO NOT CREATE)
76+
mutex_sem = sem_open(SEM_MUTEX_NAME, 0); // Flags argument is 0 when opening existing
77+
if (mutex_sem == SEM_FAILED) {
78+
perror("sem_open (Is the producer.c program running and semaphore created?)");
79+
munmap(shared_data_ptr, sizeof(SharedData));
80+
close(shm_fd);
81+
return EXIT_FAILURE;
82+
}
83+
printf("Mutex semaphore opened successfully.\n");
84+
85+
printf("Monitoring room display started. Press Ctrl+C to exit.\n");
86+
printf("Will display data every %d seconds.\n\n", MONITOR_DISPLAY_INTERVAL);
87+
88+
// 4. Monitoring loop
89+
while (keep_running) {
90+
// Wait for semaphore
91+
if (sem_wait(mutex_sem) == -1) {
92+
if (keep_running)
93+
perror("sem_wait in consumer"); // Don't print error if shutting down
94+
break; // Exit loop on error or interruption
95+
}
96+
97+
float max_temp = -FLT_MAX;
98+
float min_temp = FLT_MAX;
99+
int hottest_workshop_idx = -1;
100+
int coldest_workshop_idx = -1;
101+
int valid_data_found = 0;
102+
103+
for (int i = 0; i < NUM_WORKSHOPS; ++i) {
104+
// Check if the workshop data looks initialized (not default 0.0 or some other sentinel)
105+
// For this example, any non-zero temp can be considered, or rely on producer to fill.
106+
// A more robust way would be a 'valid' flag per workshop or timestamp.
107+
if (shared_data_ptr->workshops[i].temperature != 0.0f || shared_data_ptr->workshops[i].humidity != 0.0f) {
108+
valid_data_found = 1; // At least one workshop has some data
109+
}
110+
111+
float current_temp = shared_data_ptr->workshops[i].temperature;
112+
113+
if (current_temp > max_temp) {
114+
max_temp = current_temp;
115+
hottest_workshop_idx = i;
116+
}
117+
if (current_temp < min_temp) {
118+
min_temp = current_temp;
119+
coldest_workshop_idx = i;
120+
}
121+
}
122+
123+
// Release semaphore
124+
if (sem_post(mutex_sem) == -1) {
125+
perror("sem_post in consumer");
126+
break; // Exit loop on error
127+
}
128+
129+
// Display data
130+
if (hottest_workshop_idx != -1 && coldest_workshop_idx != -1 && valid_data_found) {
131+
printf("--- Monitoring Update (%s", ctime(&(time_t){ time(NULL) })); // ctime adds newline
132+
printf(" Highest Temp: Workshop %d (%.2f C, %.2f %% Humidity)\n",
133+
shared_data_ptr->workshops[hottest_workshop_idx].workshop_id,
134+
max_temp,
135+
shared_data_ptr->workshops[hottest_workshop_idx].humidity);
136+
printf(" Lowest Temp: Workshop %d (%.2f C, %.2f %% Humidity)\n",
137+
shared_data_ptr->workshops[coldest_workshop_idx].workshop_id,
138+
min_temp,
139+
shared_data_ptr->workshops[coldest_workshop_idx].humidity);
140+
printf("---\n\n");
141+
}
142+
else if (!valid_data_found) {
143+
printf("[%s] Waiting for initial data from workshops...\n\n", ctime(&(time_t){ time(NULL) }));
144+
}
145+
else {
146+
printf("[%s] No valid temperature extremes found yet (all workshops might have same temp or no data).\n\n", ctime(&(time_t){ time(NULL) }));
147+
}
148+
fflush(stdout);
149+
150+
// Sleep for the display interval
151+
for (int i = 0; i < MONITOR_DISPLAY_INTERVAL && keep_running; ++i) {
152+
sleep(1);
153+
}
154+
}
155+
156+
// 5. Cleanup: Unmap shared memory, close file descriptor, close semaphore
157+
cleanup_ipc_consumer();
158+
159+
return EXIT_SUCCESS;
160+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// data_structures.h
2+
#ifndef DATA_STRUCTURES_H
3+
#define DATA_STRUCTURES_H
4+
5+
#include <pthread.h> // For pthread_t, though not strictly needed in Program 2 if monitor is in main
6+
#include <semaphore.h> // For sem_t
7+
#include <time.h> // For time_t (optional)
8+
9+
#define NUM_WORKSHOPS 10
10+
#define SHM_NAME "/workshop_monitoring_shm"
11+
#define SEM_MUTEX_NAME "/workshop_monitoring_mutex_sem"
12+
13+
// Min/Max values for simulation
14+
#define MIN_TEMP 10.0f
15+
#define MAX_TEMP 40.0f
16+
#define MIN_HUMIDITY 20.0f
17+
#define MAX_HUMIDITY 80.0f
18+
19+
// Interval for workshop data generation (seconds)
20+
#define WORKSHOP_UPDATE_INTERVAL 2
21+
// Interval for monitoring display (seconds)
22+
#define MONITOR_DISPLAY_INTERVAL 5
23+
24+
typedef struct {
25+
int workshop_id;
26+
float temperature;
27+
float humidity;
28+
// time_t last_updated; // Optional: timestamp of last update
29+
} WorkshopData;
30+
31+
typedef struct {
32+
WorkshopData workshops[NUM_WORKSHOPS];
33+
// Could add a generation counter or other metadata if needed
34+
// int data_ready_count; // Could be used with condition variables if within one process
35+
} SharedData;
36+
37+
#endif // DATA_STRUCTURES_H
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <stdio.h>
2+
#include <pthread.h>
3+
#include <unistd.h>
4+
#include <stdlib.h>
5+
#include <stdbool.h>
6+
7+
// Shared variables
8+
int total_count = 0;
9+
int even_count = 0;
10+
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
11+
bool running = true;
12+
13+
// Thread to report total count every 3 seconds
14+
void* report_total(void* arg) {
15+
while(running) {
16+
sleep(3);
17+
pthread_mutex_lock(&mutex);
18+
printf("Total numbers entered so far: %d\n", total_count);
19+
pthread_mutex_unlock(&mutex);
20+
}
21+
return NULL;
22+
}
23+
24+
// Thread to report even count every 5 seconds
25+
void* report_even(void* arg) {
26+
while(running) {
27+
sleep(5);
28+
pthread_mutex_lock(&mutex);
29+
printf("Total even numbers entered so far: %d\n", even_count);
30+
pthread_mutex_unlock(&mutex);
31+
}
32+
return NULL;
33+
}
34+
35+
int main() {
36+
pthread_t total_thread, even_thread;
37+
int num;
38+
39+
// Create the reporting threads
40+
pthread_create(&total_thread, NULL, report_total, NULL);
41+
pthread_create(&even_thread, NULL, report_even, NULL);
42+
43+
printf("Enter integers (enter a negative number to exit):\n");
44+
45+
while(1) {
46+
scanf("%d", &num);
47+
48+
if(num < 0) {
49+
printf("Negative number entered. Exiting program.\n");
50+
break;
51+
}
52+
53+
pthread_mutex_lock(&mutex);
54+
total_count++;
55+
56+
if(num % 2 == 0) {
57+
even_count++;
58+
printf("%d is an even number.\n", num);
59+
} else {
60+
printf("%d is an odd number.\n", num);
61+
}
62+
pthread_mutex_unlock(&mutex);
63+
}
64+
65+
// Signal threads to terminate and wait for them
66+
running = false;
67+
pthread_join(total_thread, NULL);
68+
pthread_join(even_thread, NULL);
69+
70+
pthread_mutex_destroy(&mutex);
71+
72+
return 0;
73+
}

0 commit comments

Comments
 (0)