I need to write a program that is creating a N amount of sub processes and every single one of them adds one to a shared memory variable. My idea is to use semaphores and shared memory, but the processes are not waiting for each other and the shared memory variable is also not working as I want it.
mydefs.h
#ifndef __MYDEFS__H__ #define __MYDEFS__H__ // Includes #include <stdio.h> #include <unistd.h> #include <semaphore.h> #include <stdlib.h> #include <signal.h> #include <errno.h> #include <memory.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <sys/shm.h> #endif // __MYDEFS__H__
main.c
#include "mydefs.h" #define PROC_COUNT 3 #define INITAL_MARKER_VALUE 0 #define PID_LEN 32 char mypid[PID_LEN]; int main() { int i, shm_id; sem_t mutex; if(sem_init(&mutex,1,1) < 0) { perror("semaphore initilization"); exit(0); } shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666); if (shm_id < 0) { printf("shmget errorn"); } int *shmpointer = shmat(shm_id,0,0); memset(mypid, 0, sizeof(mypid)); sprintf(mypid, "%06d", getpid()); for(i = 0; i < PROC_COUNT; i++) { if (fork() == 0) { while(sem_wait(&mutex)!=0); execl("slaveproc", "slaveproc", mypid, (char *)0); shmpointer += 1; sem_post(&mutex); perror("n Can't exec slave program. Cause "); exit(1); } } sleep(1); printf("%dn", *shmpointer); return 0; }
slaveproc.c
#include "mydefs.h" int marker; // Marker value int main(int argc, char *argv[]) { master_pid = atoi(argv[1]); printf("n --------------------------------------"); printf("n I'm the slave proc!"); printf("n My pid: %d", getpid()); printf("n My master's pid: %d", master_pid); printf("n --------------------------------------"); for(;;) pause(); return 0; }
Advertisement
Answer
The problem (or at least “a problem”) is that mutex
is not in shared memory: it’s allocated on the stack. When you fork()
, the new process will have a completely separate copy from the old process, so calling sem_wait(&mutex)
on one process will not affect the other process’s mutex
at all.
You should put mutex
in the shared memory:
int main() { int i, shm_id; shm_id = shmget(IPC_PRIVATE, sizeof(sem_t) + 4*sizeof(int), IPC_CREAT | 0666); if (shm_id < 0) { printf("shmget errorn"); } int *shmpointer = shmat(shm_id,0,0); sem_t *mutex = shmpointer; shmpointer = (void*)shmpointer + sizeof(sem_t); if(sem_init(mutex,1,1) < 0) { perror("semaphore initilization"); exit(0); } memset(mypid, 0, sizeof(mypid)); sprintf(mypid, "%06d", getpid()); for(i = 0; i < PROC_COUNT; i++) { if (fork() == 0) { while(sem_wait(mutex)!=0); execl("slaveproc", "slaveproc", mypid, (char *)0); shmpointer += 1; sem_post(mutex); perror("n Can't exec slave program. Cause "); exit(1); } } sleep(1); printf("%dn", *shmpointer); return 0; }
You’re also never writing to the memory in shmpointer
(perhaps you meant (*shmpointer) += 1
?), but I’ll let you figure that out on your own.