I'm currently writing a small shell in C++.
Jobs and the PIDs associated with them are stored within a queue of job pointers (job *)
. When a new job is run, information about it is added to the queue. Since multiple jobs can be handled simultaneously and new jobs can be entered at the shell's console at any time, I have a signal handler to wait on jobs which are terminated.
When a job is terminated, I need to remove it's information from the active job queue and move it to my deque of terminated jobs. However, it is possible that a user's new job is being added to the queue when another job stops.
In such a case, their insert
queue operation would be suspended and my signal handler would be called, which would perform it's pop
operation.
I'm trying to understand how I can resolve this potential race condition, as I imagine corruption can occur during this process. I cannot use a mutex, as a deadlock would occur if the interrupted parent process is using the queue at the time.
I see some information about C++11
being capable of atomic operations as declared by the user, along with information regarding tasklets. I'm not sure if these are relevant to my question though.
Interestingly enough, an example shell (MSH - http://code.google.com/p/mini-shell-msh/) which I am using as a reference does not appear to do any handling of such conditions. The signal handler immediately modifies the job list, along with the main console. Perhaps there is something I am overlooking here?
As always, all feedback is appriciated.
STL::Queue
? b) Be very careful what you do in signal handlers. I think if you modify anything butsigatomic_t
variables, you have undefined behaviour. – Chilungsigatomic_t
are allowed. Are you multithreaded?) – Chilungselect
-based main loop... or use something likelibevent2
... or some polling-based library whose name escapes me. Not everything needs to me multi-threaded. Concurrent programming is very hard. – Chilung