Вы неправильно используете fork и определенно не используете разделяемую память.
Вот несколько моментов
- Вызывая fork, вы создаете копию родительского объекта, работающего в другом пространстве памяти. http://man7.org/linux/man-pages/man2/fork.2.html
- Используя execve, вы по существу удаляете старую память и заменяете ее новой, которая никак не связана с вашим родительским процессом. http://man7.org/linux/man-pages/man2/execve.2.html
Чтобы ваш код работал, вы должны использовать вместо него pthread_*
, так как он будет находиться в том же пространстве памяти и сделает вашу глобальную переменную изменчивой, поскольку gcc попытается оптимизировать ее и будет иметьстранное поведение, если так оно и есть.
Хорошо, похоже, я упустил немало очков, хотя и не совсем ошибался в своих предположениях.
Таким образом, в вашем child.c отсутствует немного кода
- Он не содержит всю инициализацию, которую вы сделали в родительском элементе, что необходимо, потому что если вы используете
execve
вы, по сути, потеряли все сопоставления памяти, которые ранее отображали в родительском процессе. - Ваши родители зацикливаются бесконечно, поэтому
shmem->count
никогда не будет равным 5, вам придется в какой-то момент сломать или изменить свойусловие в вашем дочернем коде.
Вот как должен выглядеть ваш ребенок.
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct
{
int count;
sem_t sem;
} shared;
shared *shmem;
int shmid;
key_t shmkey;
int main()
{
int alive=1;
shmkey = ftok("makefile",777);
if (shmkey == -1) {
perror("Ftok failed");
exit(-1);
}
// Get our shm id
shmid = shmget(shmkey, sizeof *shmem, 0);
if (shmid == -1) {
perror("Failed to allocate shared memory region");
exit(-1);
}
// Attach to our shared memory
shmem = (shared*)shmat(shmid, (void *)0, 0);
if (shmem == (shared *)-1) {
perror("Failed to attach to shared memory region");
exit(-1);
}
do
{
sem_wait(&(shmem->sem));
printf("%d\n", shmem->count);
if(shmem->count > 5)
{
shmem->count=0;
alive=0;
}
sem_post(&(shmem->sem));
}while(alive);
printf("I have finished %u\n", getpid());
exit(0);
}