Reputation: 1784
HI,
I have a program in which a master processes spawns N workers who will invert, each one, each row of an image, giving me an inverted image at the end. The program uses shared memory and posix semaphores, unnamed sems, more spefically and I use shmctl with IPC_RMID and sem_close and sem_destroy in the terminate() function. However, when I run the program several times, sometimes it gives me a segmentation fault and is in the first shmget. I've already modified my shmmax value in the kernel, but I can't do the same to the shmall value, I don't know why.
Can someone please help me? Why this happens and why isn't it all the time? The code seems fine, gives me what I want, efficient and so...but sometimes I have to reboot Ubuntu to be able to run it again, even thought I'me freeing the resources.
Please enlighten me!
EDIT:
Here are the 3 files needed to run the code + the makefile:
http://pastebin.com/JqTkEkPv
http://pastebin.com/v7fQXyjs
http://pastebin.com/NbYFAGYq
You have to run it like this ./invert someimage.ppm outimage.ppm (test with a small one for now please)
Here are some values that may be important:
$ipcs -lm
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 262144
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1
$ipcs -ls
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767
EDIT: the seg fault was solved! I was allocating an **array in shared memory and that was a little bit odd.So, I've allocated segment for an *array only and voilà. If you want, check the new code and comment.
Upvotes: 0
Views: 877
Reputation: 78903
Now that you posted your code we can say a bit more.
Without having read all in detail, I think the cleanup phase of your main
looks suspicious. In fact it seems to me that all your worker processes will perform that cleanup phase too.
After the fork you should more clearly distinguish what main
does and what the workers do. Alternatives:
wait
on the pid
s of the workers
and only then do the rest of
processing and cleanup.main
after the call to
worker
.exit
at the end of the worker
function.Edit after your code update:
I think still a better solution would be to do a classical wait
for all the processes.
Now let's look into your worker process. In fact these never terminate, there is no break
statement in the while (1)
loop. I think what is happening is that once there is no more work to be done
sem_wait(sem_remaining_lines)
sem_remaining_lines
sem_wait
and continuesmutex3
is also already
destroyed (or maybe even unmapped) the wait on it returns
immediatelymain
process got on destruction the data
is mapped or not and the worker
crashes (or not)As you can see you have many problems in there. What I would do to clean up this mess is
waitpid
before destroy the shared
datasem_trywait
instead of the 1 in
while (1)
. But perhaps I didn't completely understand your control flow. In any case, give them a termination condition.sem_t
family. These can be interrupted by
IO, so you definitively must
check for EINTR
on these.Upvotes: 1
Reputation: 78903
If all your sem_t
POSIX semaphores are unnamed you should only use sem_init
and sem_destroy
on them and never sem_close
.
Upvotes: 3