i am new to Sockets programming and going through the Documentation.
From a documentation i found about CloseThreadPool() function :
CloseThreadpool function. The thread pool is closed immediately if there are no outstanding callback objects that are bound to the thread pool. If there are, then the thread pool is released asynchronously when those outstanding objects are freed.
This thread pool is in a thread itself. my main thread takes input for exit. if exit is inputted i set global variable KEEP_LISTENEING to false.
How would i wait my main thread to stop/sleep untill this function truly completes in another thread ?
Use a cleanup group to wait for all callbacks. The sequence is:
CreateThreadpoolCleanupGroup()
SetThreadpoolCallbackCleanupGroup(&CallbackEnvironment, pointerCleanup, ...)
CloseThreadpoolCleanupGroupMembers(, FALSE, )
CloseThreadpoolCleanupGroup()
Related
If you have an #Async method the returns a CompletableFuture....and the future never gets completed, does spring just leak the thread? Yes, I know whomever is waiting on the results could timeout and assume exceptional completion for latter stages.....but that doesn't stop the thread. Even if you call cancel, it doesn't do shit to the running thread:
from the docs:
#param mayInterruptIfRunning this value has no effect in this
implementation because interrupts are not used to control
processing.
If I use Future instead of CompletableFuture, cancel will interrupt the thread. Unfortunately, there is no equivalent of "allOf" on Future like we have on CompletableFuture to wait for all the tasks, like so:
// wait for all the futures to finish, regardless of results
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new))
// if exceptions happened in any future, swallow them
// I don't care because I'm going to process each future in my list anyway
// we just wanted to wait for all the futures to finish
.exceptionally(ex -> null);
how are we supposed to cancel a thread that we bailed on?
if I didn't cancel it (somehow), would my pool just be down a thread forever????
I have a question about closing a WINAPI ThreadPool.
Suppose i have initialized a thread pool with a cleanup group and pushed some tasks to the thread pool with the SubmitThreadpoolWork.
I'm calling the CloseThreadPoolTask in the task's callback function.
Currently there are tasks that executing and others that pending in the thread-pool's queue.
Now, for closing the thread pool I want to use CloseThreadpoolCleanupGroupMembers function without pending for the queued tasks to finish, but I still want to get a callback to the pending task to release its user allocated resources (some that come with the task's parameters).
I saw in this thread:
Cancelling scheduled work/io/timer items in WIN32 thread pool
that the callback that i have passed to the cleanup group (PTP_CLEANUP_GROUP_CANCEL_CALLBACK) will also call to work objects that are currently executing (because they still tied to cleanup group during the execution) - obviously i don't want it to happen... Is there a way that the cleanup cancel callback will not get invoked on currently executing tasks?
Thanks!
if callback for CreateThreadpoolWork begin executed, cleanup callback for it will be not called. or if cancel callback for item will be called - PTP_WORK_CALLBACK will be never called for this item (before and after). so here really no any problem. or will be called your PTP_WORK_CALLBACK or will be called cancell callback for this item. this is mutually exclusive. so reply in topic Cancelling scheduled work/io/timer items in WIN32 thread pool containing very serious errors. i can suggest you for test insert MessageBox call in begin of PTP_WORK_CALLBACK and also another MessageBox before CloseThreadpoolCleanupGroupMembers. and you can make sure if PTP_WORK_CALLBACK begin executed - cancell callback for this item already not called.
I am trying to model a system where there are multiple threads producing data, and a single thread consuming the data. The trick is that I don't want a dedicated thread to consume the data because all of the threads live in a pool. Instead, I want one of the producers to empty the queue when there is work, and yield if another producer is already clearing the queue.
The basic idea is that there is a queue of work, and a lock around the processing. Each producer pushes its payload onto the queue, and then attempts to enter the lock. The attempt is non-blocking and returns either true (the lock was acquired), or false (the lock is held by someone else).
If the lock is acquired, then that thread then processes all of the data in the queue until it is empty (including any new payloads introduced by other producers during processing). Once all of the work has been processed, the thread releases the lock and quits out.
The following is C++ code for the algorithm:
void Process(ITask *task) {
// queue is a thread safe implementation of a regular queue
queue.push(task);
// crit_sec is some handle to a critical section like object
// try_scoped_lock uses RAII to attempt to acquire the lock in the constructor
// if the lock was acquired, it will release the lock in the
// destructor
try_scoped_lock lock(crit_sec);
// See if this thread won the lottery. Prize is doing all of the dishes
if (!lock.Acquired())
return;
// This thread got the lock, so it needs to do the work
ITask *currTask;
while (queue.try_pop(currTask)) {
... execute task ...
}
}
In general this code works fine, and I have never actually witnessed the behavior I am about to describe below, but that implementation makes me feel uneasy. It stands to reason that a race condition is introduced between when the thread exits the while loop and when it releases the critical section.
The whole algorithm relies on the assumption that if the lock is being held, then a thread is servicing the queue.
I am essentially looking for enlightenment on 2 questions:
Am I correct that there is a race condition as described (bonus for other races)
Is there a standard pattern for implementing this mechanism that is performant and doesn't introduce race conditions?
Yes, there is a race condition.
Thread A adds a task, gets the lock, processes itself, then asks for a task from the queue. It is rejected.
Thread B at this point adds a task to the queue. It then attempts to get the lock, and fails, because thread A has the lock. Thread B exits.
Thread A then exits, with the queue non-empty, and nobody processing the task on it.
This will be difficult to find, because that window is relatively narrow. To make it more likely to find, after the while loop introduce a "sleep for 10 seconds". In the calling code, insert a task, wait 5 seconds, then insert a second task. After 10 more seconds, check that both insert tasks are finished, and there is still a task to be processed on the queue.
One way to fix this would be to change try_pop to try_pop_or_unlock, and pass in your lock to it. try_pop_or_unlock then atomically checks for an empty queue, and if so unlocks the lock and returns false.
Another approach is to improve the thread pool. Add a counting semaphore based "consume" task launcher to it.
semaphore_bool bTaskActive;
counting_semaphore counter;
when (counter || !bTaskActive)
if (bTaskActive)
return
bTaskActive = true
--counter
launch_task( process_one_off_queue, when_done( [&]{ bTaskActive=false ) );
When the counting semaphore is active, or when poked by the finished consume task, it launches a consume task if there is no consume task active.
But that is just off the top of my head.
I have designed an application which is running 20 instance of a thread.
for(int i = 0;i<20;i++)
{
threadObj[i].start();
}
How can I wait in the main thread until those 20 threads finish?
You need to use QThread::wait().
bool QThread::wait ( unsigned long time = ULONG_MAX )
Blocks the thread until either of
these conditions is met:
The thread associated with this
QThread object has finished execution (i.e. when it returns from
run()). This function will return true if the thread has finished. It
also returns true if the thread has
not been started yet.
time milliseconds has elapsed. If time is
ULONG_MAX (the default), then the wait
till never timeout (the thread must
return from run()). This function
will return false if the wait timed
out.
This provides similar functionality to
the POSIX pthread_join() function.
Just loop over the threads and call wait() for each one.
for(int i = 0;i < 20;i++)
{
threadObj[i].wait();
}
If you want to let the main loop run while you're waiting. (E.g. to process events and avoid rendering the application unresponsible.) You can use the signals & slots of the threads. QThread's got a finished() singal which you can connect to a slot that remembers which threads have finished yet.
You can also use QWaitCondition
What Georg has said is correct. Also remember you can call signal slot from across threads. So you can have your threads emit a signal to you upon completion. SO you can keep track of no of threads that have completed their tasks/have exited. This could be useful if you don't want your Main thread to go in a blocking call wait.
I'm trying to spawn and then join two threads using MS VS 6.0 (2003), MS .NET Framework 1.1.
The following seems to be a reasonable solution:
CWinThread* thread1 = AfxBeginThread(worker, ¶llel_params);
CWinThread* thread2 = AfxBeginThread(worker, ¶llel_params);
WaitForSingleObject(thread1->m_hThread, INFINITE);
WaitForSingleObject(thread2->m_hThread, INFINITE);
but my main concern has to do with this statement in the documentation: "If this handle is closed while the wait is still pending, the function's behavior is undefined." When do handles get closed? Does ending the worker proc close the handle? If so, am I in trouble? Is this really a reasonable solution??
In order to be able to safely wait on the thread's handle, you should:
Start the thread suspended
Set the m_bAutoDelete member to false, so that the returned CWinThread* is not deleted automatically once the thread exits
Resume the thread
And finally wait on the handle the way you do.
Alternatively, you can start the thread suspended, then duplicate the handle, leave m_bAutoDelete as is, and finally wait on the new handle. This way the CWinThread* will indeed be deleted, but you'll still have a handle to wait on. Also, don't forget to close the handle once your done waiting on it.
If you leave your code as is, you might not even get to wait on a closed handle. If the thread exits you get to the wait function, the CWinThread* pointer might point to a deleted object, and you'll get an exception.