Created
December 26, 2024 22:07
-
-
Save jamesu/f6bd7a289647ce58b9115b5823cf8223 to your computer and use it in GitHub Desktop.
ipc_test.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <sys/wait.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
#include <semaphore.h> | |
#include <string.h> | |
#include <pthread.h> | |
typedef struct { | |
int value; | |
pthread_mutex_t mutex; | |
pthread_cond_t cond; | |
} semaphore_t; | |
void semaphore_init(semaphore_t *sem, int initial_value) { | |
pthread_mutexattr_t mutex_attr; | |
pthread_condattr_t cond_attr; | |
pthread_mutexattr_init(&mutex_attr); | |
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); | |
pthread_condattr_init(&cond_attr); | |
pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); | |
pthread_mutex_init(&sem->mutex, &mutex_attr); | |
pthread_cond_init(&sem->cond, &cond_attr); | |
sem->value = initial_value; | |
pthread_mutexattr_destroy(&mutex_attr); | |
pthread_condattr_destroy(&cond_attr); | |
} | |
void semaphore_wait(semaphore_t *sem) { | |
pthread_mutex_lock(&sem->mutex); | |
while (sem->value <= 0) { | |
pthread_cond_wait(&sem->cond, &sem->mutex); | |
} | |
sem->value--; | |
pthread_mutex_unlock(&sem->mutex); | |
} | |
void semaphore_post(semaphore_t *sem) { | |
pthread_mutex_lock(&sem->mutex); | |
sem->value++; | |
if(sem->value > 0) | |
{ | |
pthread_cond_signal(&sem->cond); | |
} | |
pthread_mutex_unlock(&sem->mutex); | |
} | |
void semaphore_destroy(semaphore_t *sem) { | |
pthread_mutex_destroy(&sem->mutex); | |
pthread_cond_destroy(&sem->cond); | |
} | |
/* | |
* An example of communicating between parent and child processes through | |
* shared memory using mmap | |
*/ | |
typedef struct TestSem_s | |
{ | |
semaphore_t sem; | |
int value; | |
} TestSem_t; | |
int main(void) { | |
void *shared_mem = NULL; | |
int data = 10; | |
uint32_t i=0; | |
pid_t child_pid = -1; | |
int child_state = -1; | |
sem_t sem; | |
shared_mem = mmap(NULL, sizeof(TestSem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1 /* fd */, 0 /* offset */); | |
TestSem_t *fuck = (TestSem_t*)shared_mem; | |
memset(fuck, 0, sizeof(TestSem_t)); | |
if (shared_mem == MAP_FAILED) { | |
perror("mmap failed"); | |
return -1; | |
} | |
semaphore_init(&fuck->sem, 0); | |
child_pid = fork(); | |
if (child_pid == 0) { | |
printf("[CHILD] Writing data=%d at addr=%p\n", data, shared_mem); | |
for (i=0; i<10; i++) { | |
sleep(1); | |
fuck->value = i+50; | |
} | |
semaphore_post(&fuck->sem); | |
printf("[CHILD]SEM POSTED\n"); | |
} else { | |
printf("[HOST]WAIT START\n"); | |
semaphore_wait(&fuck->sem); | |
printf("[HOST]Reading from addr=%p returned data=%d\n", shared_mem, fuck->value); | |
wait(NULL); | |
semaphore_destroy(&fuck->sem); | |
munmap(shared_mem, sizeof(TestSem_t)); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment