Is it possible to use fork in modern C++? - c++

Traditional C++ was very straightforward and only a library intended to create threads (like pthread) gave rise to other threads.
Modern C++ is much closer to Java with many functions being thread based, with thread pools ready to run asynchronous jobs, etc. It's much more likely that some library, including the standard library, uses threads to compute asynchronously some function, or sets up the infrastructure to do so even if it isn't used.
In that context, is it ever safe to use functions with global impact like fork?

The answer to this question, like almost everything else in C++, is "it depends".
If we assume there are other threads in the program, and those threads are synchronizing with each other, calling fork is dangerous. This is because, fork does not wait for all threads to be a synchronization point (i.e. mutex release) to fork the process. In the forked process, only the thread that called fork will be present, and the others will have been terminated, possibly in the middle of a critical section. This means any memory shared with other threads, that wasn't a std::atomic<int> or similar, is an undefined state.
If your forked process reads from this memory, or indeed expects the other threads to be running, it is likely not going to work reliably. However, most uses of fork actually have effectively no preconditions on program state. That is because the most common thing to do is to immediately call execv or similar to spawn a subprocess. In this case your entire process is kinda "replaced" by some new process, and all memory from your old process is discarded.
tl;dr - Calling fork may not be safe in multithreaded programs. Sometimes it is safe; like if no threads have spawned yet, or evecv is called immediately. If you are using fork for something else, consider using a thread instead.
See the fork man page and this helpful blog post for the nitty-gritty.

To add to peteigel's answer, my advice is - if you want to fork, do it very early, before any other threads than the main thread are started.
In general, anything you can do in C, you can do in C++, since C++, especially on Linux with clang or gcc extensions, is pretty darn close to a perfect superset of C. Of course, when there are good portable APIs in std C++, use them. The canonical example is preferring std::thread over pthreads C API.
One caveat is pthread_cancel, which must be avoided on C++ due to exceptions. See e.g. pthread cancel harmful on C++.
Here is another link that explains the problem:
pthread_cancel while in destructor
In general, C++ cleanup handling is in general easier and more elegant than C, since RAII is part and parcel of C++ culture, and C does not have destructors.

Related

Using system() in a thread C++

I want to use the method system() in a (non-main) thread(pthread) in C++. For example,
system("/path/to/some/script.sh");
Is this permitted? If so, is it safe and are there any precautions I should take?
The reason I'm asking is that I've had the following comment from a code reviewer:
"The rule is system() can only be called from a single-threaded process. I think you need to move your new code to a separate application."
Is the first sentence of the comment valid?
As of GNU/Linux implementation of system, it modifies the process signal mask during command execution. In multithreaded program, we're in for nasty surprises, e.g. if another thread forks at the same time.
I wouldn't do it for a wide variety of different reasons, the problem with signal masks just being one.
In general, fork and threads are a tricky mix and need to be handled with care. The existing library functions were likely not written with a multi-threaded program in mind.

Is there any movement towards specifying interaction of C++ exceptions and pthread cancellation?

The GNU C library uses DWARF2 unwinding for pthread cancellation these days, so that both C++ exceptions and pthread cancellation cleanup handlers get called through a common call frame unwinding process which invokes destructors for automatic objects as necessary along the way. However, as far as I can tell there is still no standard that specifies the interaction between (POSIX) threads and C++, and presumably an application wishing to be portable should assume that throwing exceptions out of cancellation cleanup contexts is just as undefined as calling longjmp out of them, and that cancelling a thread that has live automatic objects with non-trivial destructors is also undefined behavior.
Is there any standardization process in progress that addresses this interaction, or is it something that can be expected to be undefined well into the future? Does C++11 have any analogous notion to POSIX thread cancellation in its thread support?
As someone who sits on ISO/IEC SC22 which encompasses WG14 (C), WG15 (POSIX) and WG21 (C++), I can tell you that the quick answer is no, C++ exceptions and thread cancellation are not going to see one another any time soon. C11 and C++11 make no mention of thread cancellation, and are highly if not extremely unlikely to recognise it before the next major standards release in about ten years time.
The longer answer comes down to how standards work. Basically ISO can only standardise what everyone can come to agree upon, and people do not agree when it comes to thread cancellation. The whole idea of a thread of execution having to dump state before every cancellable system call goes against the whole ethos of modern software development. It causes immense problems for compiler optimisation because unlike C++ exception throws, a thread cancel is defined to be the same as calling thread_terminate(self) which explicitly precludes doing anything additional (and even cancellation handlers aren't reliably called on many implementations), and I don't think that the thread cancellation supporters would disagree it's a bad solution.
The problem is that the only proper alternative is to reissue the POSIX i/o API with async completion variants. And the problem with that is that different POSIX implementations think of async completion very differently. I mean, we can't even agree on a standard for kernel wait queues, so until that can be achieved an async i/o API is a long way off. I have a proposal to make some movement on kernel wait queues for the next standards TC/TR, but the proposed object is deliberately extremely simplistic.
What we've tried to do in C11/C++11 is for the threading API to always have non-blocking versions - there is only one API in there which can't be done non-blocking which is thread_join() (there is no thread_timedjoin()) and I plan to personally submit an errata on that after I have Austin Working Group approval. In all other cases, one can always construct something which polls which isn't efficient, but is program correct.
In the longer run, personally speaking I see plenty of good reason to add exception handling to C following similar semantics to C++. You wouldn't have object support necessarily (I would actually support adding non-virtual objects to C too personally), but you would have the concept of stack unwound lambda function calls. That would let us formalise hacks like thread cancellation with a properly defined mechanism. It also makes writing fault tolerant C much easier and safer by letting you write the unwind as you write the wind, and lets old C transparently interop with new C.
Regarding throwing exceptions from within exception handling, me personally I think we need to do something better than just always auto invoking terminate(). As unwinding may cause the construction of new objects, or indeed any other source of exception throws, I personally would greatly prefer if every reasonable attempt is made to unwind the whole stack before terminating the process.
So, in short, expect POSIX thread cancellation to continue to be viewed as undefined, and the strong chances are in the long run it'll get deprecated in favour of something better.
BTW, generally POSIX thread cancellation is highly unportable between implementations, so any code which uses POSIX thread cancellation is effectively relying on platform-specific behaviour which is identical to using non-POSIX APIs. If you want your code to be portable, don't use POSIX thread cancellation. Instead use select() or poll() including a magic "please stop thread now" file descriptor. In my own C++ code, I actually have a system API wrapper macro which tests for this magic file descriptor and throws a special C++ exception. This ensures identical behaviour on all platforms, including Windows.

Cross-Platform Threading/Forking-with-static-variables in C/C++

I'm trying to write a server program which can keep a track of the number of instances of some object.
At the moment I'm using a static int which is incremented during the object's constructor:
class myObj{
public:
static int numOfInstances;
myObj();
};
int myObj::numOfInstances = 0;
myObj::myObj(){
this->numOfInstances = ++myObj::numOfInstaces
}
But I also want to fork for each connection, with a child process handling each one and the parent constantly listening for new connections.
If I use fork(), each child process is unaware of new connections, and new objects created due to them.
I think threading might be a solution, but I'm not sure if threading is cut out for this kind of thing (most of the program would run in the thread). Even if it is, it's not in the ANSI standard, so I'd rather find a solution which uses fork.
If there's no sane solution with fork, which threading solution do people recommend? I'm writing for Linux, but I'd much prefer a cross-platform solution.
Multiprocessing is not part of the C++ standard. However, if you are on a POSIX system (where you have fork()), you can obtain shared memory from the operating system; look at the shmget() familiy of functions. You will need some synchronisation mechanism for access to the shared memory (like a mutex or a semaphore); those are also provided.
I suggest man shm_overview and man sem_overview as starting points.
I don't really know how resource sharing works on POSIX systems (so I can't tell you whether to simply fork() or use threads) but there's the portable Boost.Thread library, in addition to pthreads, if you decide to go that way.
Note that there's also a race condition in your code; two threads (whether in the same process or not, so in either case) cannot write to the same location without some kind of synchronization.

Using asynchronous method vs thread wait

I have 2 versions of a function which are available in a C++ library which do the same task. One is a synchronous function, and another is of asynchronous type which allows a callback function to be registered.
Which of the below strategies is preferable for giving a better memory and performance optimization?
Call the synchronous function in a worker thread, and use mutex synchronization to wait until I get the result
Do not create a thread, but call the asynchronous version and get the result in callback
I am aware that worker thread creation in option 1 will cause more overhead. I am wanting to know issues related to overhead caused by thread synchronization objects, and how it compares to overhead caused by asynchronous call. Does the asynchronous version of a function internally spin off a thread and use synchronization object, or does it uses some other technique like directly talk to the kernel?
"Profile, don't speculate." (DJB)
The answer to this question depends on too many things, and there is no general answer. The role of the developer is to be able to make these decisions. If you don't know, try the options and measure. In many cases, the difference won't matter and non-performance concerns will dominate.
"Premature optimisation is the root of all evil, say 97% of the time" (DEK)
Update in response to the question edit:
C++ libraries, in general, don't get to use magic to avoid synchronisation primitives. The asynchronous vs. synchronous interfaces are likely to be wrappers around things you would do anyway. Processing must happen in a context, and if completion is to be signalled to another context, a synchronisation primitive will be necessary to do that.
Of course, there might be other considerations. If your C++ library is talking to some piece of hardware that can do processing, things might be different. But you haven't told us about anything like that.
The answer to this question depends on context you haven't given us, including information about the library interface and the structure of your code.
Use asynchronous function because will probably do what you want to do manually with synchronous one but less error prone.
Asynchronous: Will create a thread, do work, when done -> call callback
Synchronous: Create a event to wait for, Create a thread for work, Wait for event, On thread call sync version , transfer result, signal event.
You might consider that threads each have their own environment so they use more memory than a non threaded solution when all other things are equal.
Depending on your threading library there can also be significant overhead to starting and stopping threads.
If you need interprocess synchronization there can also be a lot of pain debugging threaded code.
If you're comfortable writing non threaded code (i.e. you won't burn a lot of time writing and debugging it) then that might be the best choice.

Is there a disadvantage to using boost::interprocess::interprocess_semaphore within a single multithreaded c++ process?

The disadvantage would be in comparison to a technique that was specialized to work on threads that are running within the same process. For example, does wait/post cause the whole process to yield, rather than just the executing thread, even though anyone waiting for a post would be within the same process?
The semaphore would be used, for example, to solve a producer/consumer problem in a shared buffer between two threads in the same process.
Are there any reasonable alternatives?
Use Boost.Thread condition variables as shown here. The accompanying article has a good summary of Boost.Thread features.
Using interprocess semaphores will work but it's likely to place a tax on your execution due to use of unnecessarily heavyweight underlying OS locking primitives (named kernel objects in Windows, for example).