I'm using IOmniParallelJoin to compute the several tasks in parallel with NoWait function because I want the GUI to stay responsive. But I also need to know when the computation is finished. Is there any event which is triggered in such case?
You can either use the OnStop function to inject some code or use a Task Configuration via TaskConfig and assign the code via OnTerminated. The difference is that OnStop is called inside one of the worker threads while OnTerminated is called inside the main thread.
Related
I am using vfork() in glibc and according to vfork()'s man page:
Fork handlers established using pthread_atfork(3) are not called
when a multithreaded program employing the NPTL threading library
calls vfork(). Fork handlers are called in this case in a
program using the LinuxThreads threading library.
On NPTL fork handlers are not being called.
In my specific case I need this protection to be engaged so fork handlers will be called the same way as when calling fork().
Is there a way to cause pthread library to call registered handlers or even call them manually?
I thought of using clone() as it gives more precise control of the cloned process but it also avoids fork handlers:
Handlers registered using pthread_atfork(3) are not executed
during a clone call.
Also read how to reset handlers registered by pthread_atfork - in my case I don't want to remove handlers but only call them.
Thanks.
Is there a way to cause pthread library to call registered handlers or even call them manually?
If you succeeded in doing this, your program would become corrupt. There is a reason pthread_atfork handlers aren't called on vfork.
A typical usage of pthread_atfork handlers is to guarantee that any locks held in the parent process are in a consistent state in both the child and the parent after the fork.
Without handlers, suppose thread T1 is holding lock L, and thread T2 calls fork. Since only T2 will be replicated into the child, L will remain locked forever. If T2 needs that lock (say it was the malloc lock), T2 will deadlock (with T1 which doesn't exist in the child).
The solution: pthread_atfork handlers. In the parent process prepare() will acquire L, and both parent() and child() handlers will unlock their own instance of L in the parent and child processes respectively. Everything is happy1.
Now consider what happens if you do the same after vfork. prepare() acquires L as expected, but when you call parent() and child(), they unlock the same instance of L (because parent and child processes share memory). Thus L gets unlocked twice, corrupting it!
1 In practice calling either fork or vfork in a multithreaded program is fraught with peril, and doing this safely in the presence of arbitrary libraries is near impossible.
Good morning,
I would like to use a TThread object to process numeric values.
On a recurring basis (through the TTimer object), different/updated values are always presented in processing.
Basically:
The first time I create and launch the TThread which is actually executed but not deleted.
Subsequently (by TTimer), I get new values for TThread to process.
Request:
Is there a way to "restart" the TThread with the new values, without creating a new TThread object every time? (TThread already exists)
This would save time, since the values would always use the space allocated in the first TThread creation.
A TThread (or any other kind of thread wrapper, for that matter) cannot be "restarted" once it has finished running. All you can do is free it.
So, to do what you are asking for, you would need to make the thread's Execute() method run a loop that processes your numeric values on each iteration as needed, until you are ready to signal the thread to terminate itself.
You will have to implement your own thread-safe system to push new numerics into the thread when needed, and to make the thread wait for new numerics to arrive between each loop iteration. For instance, you could push values into a TThreadList or TThreadedQueue, signaling a waitable TEvent or TMonitor on each push, and then the thread loop can wait on that signal before pulling values on each iteration.
Otherwise, consider using TTask instead of TThread. Tasks can utilize thread pooling internally, so you can just create a new TTask each time you have a new numeric to process, and let it pull out an available thread from the pool, and put the thread back in the pool when finished.
Examples:
Asynchronous method with its own dispatching:
// Library
func asyncAPI(callback: Result -> Void) {
dispatch_async(self.queue) {
...
callback(result)
}
}
// Caller
asyncAPI() { result in
...
}
Synchronous method with exposed dispatch queue:
// Library
func syncAPI() -> Result {
assert(isRunningOnCorrectQueue())
...
return result
}
// Caller
dispatch_async(api.queue) {
let result = api.syncAPI()
...
}
These two examples behave the same but I am looking to learn whether one of these ends up complicating a larget codebase more than the other, especially when there is a lot of asynchrony.
I would argue against both of the patterns you propose.
For the first pattern (where the API manages it's own backgrounding) I see little or no benefit to doing it this way, as opposed to leaving it to the caller. If you want to use a private, serial queue to protect data (or any other sort of critical section) internal to your API, that's fine, but that queue should be private, and it should specifically not target any public, non-global-concurrent queue (Note: it should especially not target the main queue). Ideally, the primary implementation of your API would also take a second parameter, so callers can specify on which queue to invoke the callback. (People can work around the lack of such a parameter by passing a callback block that re-dispatches to their desired queue, but I think that's clunkier than having an extra, optional parameter.) This puts the API consumer in complete control of the concurrency, while preserving your freedom to use queues internally to protect state.
As to the second approach, it's my opinion that we all should avoid creating new synchronous, blocking API. When you provide a synchronous, blocking API and don't provide a callback-based version, that means that you have denied consumers of your API any opportunity to avoid blocking. When you only provide synchronous, blocking API, then if someone wants to call your API in the background, at least one thread (in addition to any additional threads that your API consumes behind the scenes) will be consumed from the finite number of threads available to each process. (In the worst case this can lead to starvation conditions that are effectively deadlocks.)
Another red flag with this second example is that it vends a queue; Any time an API vends a queue, something is amiss. As mentioned, if you want to use a private serial queue to protect state or other critical sections internal to your API, go for it, but don't expose that queue to the outside world. If nothing else, it unnecessarily exposes details of your implementation. In looking at the system framework headers, I couldn't find a single case where a dispatch_queue_t was vended where it wasn't immediately obvious that the intent was for the API consumer to push in the queue, and not read it out.
It's also worth mentioning that these patterns are problematic regardless of whether your workload is CPU-bound or IO-bound. If it's CPU-bound, then not managing your own dispatch gives consumers of the API explicit control over how this CPU work is executed. If your workload is IO-bound, then you should use the OS- and libdispatch-provided asynchronous IO mechanisms (dispatch_io, dispatch_sources, kevent, etc) to avoid consuming a thread (or more than one) for the duration of your work.
Another answer here implied that forcing consumers to manage their own concurrency leads to "boilerplate" code. If you feel that the burden of API consumers potentially having to wrap calls to your API with dispatch_async is too great, then feel free to provide a convenience overload that dispatches to the default global concurrent queue, but please always leave the version that allows API consumers the ability to explicitly manage their own concurrency.
If, on the other hand, all this is internal to the implementation, and not part of the public API, then do whatever is most expedient, knowing that you can refactor the implementation behind the public API any time in the future.
As you said, the 2 generally accomplish the same thing but the first is more preferable in most scenarios. There are several benefits to using the first method.
The API is simpler. You simply call the method and provide code for the callback block.
Less boilerplate code, No typing dispatch_async every time you want to call it as it is just included in the method itself.
Less room for bugs/errors. By wrapping the asynchronous logic inside the method itself, you ensure that it is called on the right queue internally without the caller having to worry about any of that.
Touching on the last point, you also have finer control over the queue itself. Let's say you are trying to perform certain tasks on a particular queue. It is way simpler to simply wrap the code in a GCD call on that queue a single time rather than having to remember to reuse that same queue every time you want to call the method.
My server must print some reports about its work. How can I use visual objects such as labels, edit boxes in the OneEecute event?
The same rule, for not modifying VCL objects in any thread except main thread, is valid here too. You should not change any of VCL controls in OnExecute event-handler, because that code will be run in the context of a worker thread spawn by Indy for every connection.
If you need to change graphical user interface, do it using Synchronize or Queue methods, or use a custom notification mechanism for notifying the main thread to do the GUI modification for you.
If you want to call Synchronize or Queue methods, you have to type-cast TIdYarn to TIdYarnOfThread which derives from TIdYarn and implements it with threads:
// Calling MyMethod using Synchornize inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MyMethod);
// Calling MyMethod using Queue inside TIdTcpServer.OnExecute event-handler
TIdYarnOfThread(AContext.Yarn).Thread.Queue(MyMethod);
The documentation of delphi says that the WaitFor function for TMutex and others sychronization objects wait until a handle of object is signaled.But this function also guarantee the ownership of the object for the caller?
Yes, the calling thread of a TMutex owns the mutex; the class is just a wrapper for the OS mutex object. See for yourself by inspecting SyncObjs.pas.
The same is not true for other synchronization objects, such as TCriticalSection. Any thread my call the Release method on such an object, not just the thread that called Acquire.
TMutex.Acquire is a wrapper around THandleObjects.WaitFor, which will call WaitForSingleObject OR CoWaitForMultipleHandles depending on the UseCOMWait contructor argument.
This may be very important, if you use STA COM objects in your application (you may do so without knowing, dbGO/ADO is COM, for instance) and you don't want to deadlock.
It's still a dangerous idea to enter a long/infinite wait in the main thread, 'cause the only method which correctly handles calls made via TThread.Synchronize is TThread.WaitFor and you may stall (or deadlock) your worker threads if you use the SyncObjs objects or WinAPI wait functions.
In commercial projects, I use a custom wait method, built upon the ideas from both THandleObjects.WaitFor AND TThread.WaitFor with optional alertable waiting (good for asynchronous IO but irreplaceable for the possibility to abort long waits).
Edit: further clarification regarding COM/OLE:
COM/OLE model (e.g. ADO) can use different threading models: STA (single-threaded) and MTA (multi or free-threaded).
By definition, the main GUI thread is initialized as STA, which means, the COM objects can use window messages for their asynchronous messaging (particulary when invoked from other threads, to safely synchronize). AFAIK, they may also use APC procedures.
There is a good reason for the CoWaitForMultipleHandles function to exist - see its' use in SyncObjs.pas THandleObject.WaitFor - depending on the threading model, it can process internal COM messages, while blocking on the wait handle.