How can I delete unused shared memory and semaphores?
Check man ipcrm
.
ipcrm - remove a message queue, semaphore set or shared memory id
Does the server terminate normally? If so you can have it call shmdt()
before exiting.
If it is crashing, then that's a little harder. One thing is to have it use shmctl
to
see how many processes have the shm
attached. If it's 0, then you are obviously not the client.
There's also a flag you can set on shm segments IPC_RMID
, although the usage seems a little ambiguous.
Remove posix shared memory when not in use?
No - at lest on Linux, the kernel doesn't contain anything that can do this. It's up to some application to call shm_unlink() at some point to get rid of a shared memory segment.
Handling SIGINT with shared memory and semaphores
The reason for the behaviour you are seeing is the way the signal handler is being installed:
signal(SIGINT, handleSIGINT);
By default, signal
enables the SA_RESTART
flag. Which means that the sem_wait
will be restarted after the signal handler has been called.
This is one of the main reasons for using sigaction
instead of signal
. Change the above line to the below code and it should work as you require.
struct sigaction saction;
saction.sa_handler = handleSIGINT;
sigemptyset(&saction.sa_mask);
saction.sa_flags = 0;
sigaction (SIGINT, &saction, NULL);
Not directly part of your question but it is advisable to call sem_unlink
on SEM_1
and SEM_2
as well as check the return values of the sem_open
calls. Since O_EXCL
is set in the sem_open
it will fail if you run the program again after force terminating a previous invocation with kill
.
Programming in UNIX - Semaphores,shared memory in C
You have several problems with your code.
You declare your
p
variable as follows:int **p;
But the actual type of your array is
int[MAXSIZE][MAXSIZE]
. Although those can both be considered 2-dimensional arrays, they are not at all the same type and do not share the same structure in memory:int **
is a pointer to a pointer to an integer. When used as a 2-dimensional array, it describes a 2-level array. The first level (dereferencing the pointer once) contains an array ofint *
pointers that each point to 1-dimensional arrays of integers.int[MAXSIZE][MAXSIZE]
is a flat 2-dimentional array. It is a single pointer to an array ofMAXSIZE*MAXSIZE
integers. It has the same memory structure as the 1-dimensional arrayint[MAXSIZE*MAXSIZE]
even though it offers the convenience of using 2 levels of subscripts.
Passing around pointers to
type[][]
-style arrays in C is non-intuitive and very difficult to get right. I don't advise doing it. You might consider passing pointers to yourmatrix
type instead. Still, it is possible to get it to work with this declaration:typedef int array2d[MAX_SIZE][MAX_SIZE];
array2d *p;then you have to change the
m
parameter inreader
andwriter
toarray2d *m
instead orint **m
and use it as*m
instead of justm
. This gets ugly. Like I said, consider using yourmatrix
type instead.This problem should have been caught by the compiler. It should have been giving you lots of type mismatch warnings. Make sure you always compile with
gcc -Wall
and aim to have your program compile with no errors and no warnings.In
init()
, you setp
too early. You should set it at the end of the function aftersh_mem
has been assigned, not at the start of the function.You are
fork()
ing too many processes in yourmain()
function, as discussed in comments above. You probably meant to callfork()
only once each time through thefor
loop, not twice.You don't wait until the writers have finished filling out the shared memory structure before you go ahead and read its contents.
Note that even if you move your
wait(NULL)
before the call toreader()
, that's not enough, sincewait(NULL)
will only wait for one child process to complete, not all of them.
In general, you should compile your program with warnings enabled, pay attention to the warnings, and fix them before wondering what might be wrong with your program. If it still does something unexpected, you should run it under a debugger, use breakpoints, inspect variables, and try to take a look at what's happening. Using these two techniques, you probably would have solved your problem without needing to post here.
Re: Shared Memory and Semaphores
If my understanding of your question is correct, it is duplex.
With shared memory, both processes could communicate both ways, not just with one as the reader and one as the writer. Pipes only allow either reading or writing, but you can overcome this by using two pipes (although message queues are a better option).
Related Topics
What Is the "Current" in Linux Kernel Source
How to Execute Script in The Current Shell on Linux
How to Terminate a Sleeping Thread in Pthread
Concatenating Two String Variables in Bash Appending Newline
Adding Support for Menuconfig/Kconfig in My Project
Selecting a Linux I/O Scheduler
Profiling a (Possibly I/O-Bound) Process to Reduce Latency
Tracking Actively Used Memory in Linux Programs
How to Start Gvim with a Maximized Window
Unshare --Pid /Bin/Bash - Fork Cannot Allocate Memory
How to Recover or Change Oracle Sysdba Password
How to Find The Processor Queue Length in Linux
What Is The Point of "Grep -Q"
Linux: Large Int Array: Mmap Vs Seek File
Smbclient - Send All Files in Directory