I have the following code written in C++/CX:
TaskPool^ TaskPool::Instance::get()
{
// Prevent acquiring the critical section for a static initialization
// after it's been properly initialized.
if (TaskPool::_instance == nullptr) {
static CRITICAL_SECTION section;
CriticalSection lock(§ion);
if (TaskPool::_instance == nullptr) {
_instance = ref new TaskPool();
InitializeCriticalSection(GetCriticalSection());
}
}
return _instance;
}
TaskPool^ TaskPool::_instance;
CRITICAL_SECTION TaskPool::_criticalSection;
void Threading::TaskPool::TaskRun(Concurrency::task<void> & task)
{
Log::LogMessage(this->GetType()->FullName, Level::Debug, "TaskRun [entering]");
EnterCriticalSection(GetCriticalSection());
Log::LogMessage(this->GetType()->FullName, Level::Debug, "TaskRun [entered]");
create_task(task).then([this]() {
Log::LogMessage(this->GetType()->FullName, Level::Debug, "TaskRun [leaving]");
LeaveCriticalSection(GetCriticalSection());
Log::LogMessage(this->GetType()->FullName, Level::Debug, "TaskRun [left]");
});
}
TaskPool is a task dispatcher that uses a CRITICAL_SECTION to dispatch concorrent tasks synchronously. I've read here and confirmed in several other places that critical sections are reentrant. However, I'm failing to replicate this behaviour.
Threading.TaskPool <Debug> TaskRun [entering]
Threading.TaskPool <Debug> TaskRun [entered]
Threading.TaskPool <Debug> TaskRun [leaving]
Threading.TaskPool <Debug> TaskRun [left]
Threading.TaskPool <Debug> TaskRun [entering]
Threading.TaskPool <Debug> TaskRun [entering]
As you can see several tasks are being dispatched. However, even though the first task seems to work well, other tasks added to the pool are not being dispatched. For some reason, the critical section is not entered and the thread seems to hang. If the critical sections are recursive, what else could explain this behaviour?
Related
I have some problems designing a Signal/Slot system in C++11.
My main design goals are: simple but still offering some features and thread safe.
My personal opinion on a Signal/Slot system is that emitting should be as fast as possible. Because of that I try to keep the slot list inside the signal tidy. Many other Signal/Slot systems leave disconnected slots empty. That means more slots to iterate and checking slot validity during signal emission.
Here is the concrete problem:
Signal class have one function for emitting and one function for disconnecting a slot:
template<typename... Args>
void Signal<void(Args...)>::operator()(Args&&... args)
{
std::lock_guard<std::mutex> mutex_lock(_mutex);
for (auto const& slot : _slots) {
if (slot.connection_data->enabled) {
slot.callback(std::forward<Args>(args)...);
}
}
}
template<typename... Args>
void Signal<void(Args...)>::destroy_connection(std::shared_ptr<Connection::Data> connection_data)
{
std::lock_guard<std::mutex> mutex_lock(_mutex);
connection_data->reset();
for (auto it = _slots.begin(); it != _slots.end(); ++it) {
if (it->connection_data == connection_data) {
*it = _slots.back(); _slots.pop_back();
break;
}
}
}
This works fine until one tries to make a connection that disconnects itself when signal i emitted:
Connection con;
Signal<void()> sig;
con = sig.connect([&]() { con.disconnect(); });
sig();
I have two problems here:
The emit function must probably be redesigned because slots can potentially be removed when iterated.
There are two mutex locks inside the same thread.
Is it possible to make this work (maybe with recursive mutex?), or should I redesign the system to not interfere with slots list and just leave empty slots (as many other similar projects do) when disconnecting the signal?
Is it possible in any language to kill a thread while it is sleeping/waiting?
My scenario:
I have two threads, one is constantly looking for a rising edge in a data stream, lets call it EdgeThread, and one is setting variables based off the difference between rising edges, lets call it DifThread. The main program is plotting this data.
If EdgeThread detects another rising edge before DifThread finishes setting its variables (sleeping .5 seconds between each variable change), DifThread needs to immediately stop and relaunch, even if it is sleeping.
Languages like Java or any of the languages in the .NET platform support some form of thread wait/notify mechanism.
The idea is that instead of simply having the thread sleep for a period of time, you have the thread wait on an object to be signaled while specifying a timeout period on the waiting time, effectively behaving similarly to a sleep.
Here is a very contrived example inspired by your requirement description that illustrates how the mechanism works using .NET/C# (you can try out this little example yourself):
private static readonly object objLock = new object();
private static volatile bool shouldIRelaunch = false;
static void Main(string[] args)
{
Thread difThread = new Thread(() =>
{
while (!shouldIRelaunch)
{
Console.WriteLine("difThread - doing some work...");
// Now, instead of sleeping, perform a wait which a pulse can interrupt.
lock (objLock)
{
Monitor.Wait(objLock, 500);
}
}
Console.WriteLine("difThread - Exiting thread...");
});
Thread edgeThread = new Thread(() =>
{
Console.WriteLine("edgeThread - sleeping for a few seconds...");
Thread.Sleep(5000);
lock (objLock)
{
shouldIRelaunch = true;
Monitor.Pulse(objLock);
Console.WriteLine("edgeThread - Notiying difThread thread to interrupt the wait");
}
});
difThread.Start();
edgeThread.Start();
}
The above code snippet produces the following output:
difThread - doing some work...
edgeThread - sleeping for a few seconds...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
difThread - doing some work...
edgeThread - Notiying difThread thread to interrupt the wait
difThread - Exiting thread...
Relevant documentation for .NET languages: Monitor.Wait(), Monitor.Pulse().
For Java: Guarded Blocks
Java also has the notion of interrupting a sleep that may be of interest to you. See here for more information: Interrupts
UINT __stdcall CExternal::WorkThread( void * pParam)
{
HRESULT hr;
CTaskBase* pTask;
CComPtr<IHTMLDocument3> spDoc3;
CExternal* pThis = reinterpret_cast<CExternal*>(pParam);
if (pThis == NULL)
return 0;
// Init the com
::CoInitializeEx(0,COINIT_APARTMENTTHREADED);
hr = ::CoGetInterfaceAndReleaseStream(
pThis->m_pStream_,
IID_IHTMLDocument3,
(void**)&spDoc3);
if(FAILED(hr))
return 0;
while (pThis->m_bShutdown_ == 0)
{
if(pThis->m_TaskList_.size())
{
pTask = pThis->m_TaskList_.front();
pThis->m_TaskList_.pop_front();
if(pTask)
{
pTask->doTask(spDoc3); //do my custom task
delete pTask;
}
}
else
{
Sleep(10);
}
}
OutputDebugString(L"start CoUninitialize\n");
::CoUninitialize(); //release com
OutputDebugString(L"end CoUninitialize\n");
return 0;
}
The above the code that let my thread hang, the only output is "start CoUninitialize".
m_hWorker_ = (HANDLE)_beginthreadex(NULL, 0, WorkThread, this, 0, 0);
This code starts my thread, but the thread can't exit safely, so it waits. What the problem with this code?
The problem is not in this code, although it violates core COM requirements. Which says that you should release interface pointers when you no longer use them, calling IUnknown::Release(), and that an apartment-threaded thread must pump a message loop. Especially the message loop is important, you'll get deadlock when the owner thread of a single-threaded object (like a browser) is not pumping.
CoUninitialize() is forced to clean up the interface pointer wrapped by spDoc3 since you didn't do this yourself. It is clear from the code that the owner of the interface pointer actually runs on another thread, something to generally keep in mind since that pretty much defeats the point of starting your own worker thread. Creating your own STA thread doesn't fix this, it is still the wrong thread.
So the proxy needs to context switch to the apartment that owns the browser object. With the hard requirement that this apartment pumps a message loop so that the call can be dispatched on the right thread in order to safely call the Release() function. With very high odds that this thread isn't pumping messages anymore when your program is shutting down. Something you should be able to see in the debugger, locate the owner thread in the Debug + Windows + Threads window and see what it is doing.
Deadlock is the common outcome. The only good way to fix it is to shut down threads in the right order, this one has to shut down before the thread that owns the browser object. Shutting down a multi-threaded program cleanly can be quite difficult when threads have an interdependency like this. The inspiration behind the C++11 std::quick_exit() addition.
Is it possible to pause a different task than the one on behalf of which the kernel is currently executing? To stop the current task, one can just set it to inactive and call schedule, but what about a different one?
What I have currently:
void disable_thread(struct task_struct *tsk) {
if (tsk->state == TASK_RUNNING) {
/*
* A running task - mark it stopped and wait for it to be descheduled
*/
tsk->state = TASK_INTERRUPTIBLE;
wait_task_inactive(tsk, TASK_INTERRUPTIBLE);
} else if (tsk->state == TASK_INTERRUPTIBLE || tsk->state == TASK_UNINTERRUPTIBLE) {
/*
* // TODO: what to do with tasks already waiting for something else?
*/
} else {
/*
* This task's state seems to indicate that it's dead, no need to disable it anymore.
*/
}
}
Stopping a running thread seems to work this way, but what can we do if the thread is already waiting for something else (e.g. waiting to acquire a lock), to prevent it from restarting even if it would get the lock?
I'm implementing a security feature, and can give more context if needed.
Thanks in advance.
I currently trying to find a solution, how to ensure that a test fails if an exception occurs in a thread which is spawn by the test method.
I DON'T want to start a discussion about more than one thread in a unit test. => "unit test".Replace("unit","integration");
I already read a lot of threads in several forums, I know about CrossThreadTestRunner, but I'm searching for a solution whichs integrates into nunit, and does not require to rewrite a lot of tests.
The reason that exceptions on non-test threads (i.e. other spawned threads) do not cause tests to fail is that NUnit is configured by default to use legacyUnhandledExceptionPolicy which is a .Net process level setting which can be applied via app.config, i.e.:
<legacyUnhandledExceptionPolicy enabled="1"/>
Enabling this setting (i.e. setting it to "1") causes exceptions which do not occur on the main thread to be ignored.
I wrote an article which goes into more detail in reference to this issue with the ReSharper test runner, but it applies equally to the NUnit test runner:
https://web.archive.org/web/20101006004301/http://gojisoft.com/blog/2010/05/14/resharper-test-runner-hidden-thread-exceptions/)
ReSharper test runner – hidden thread exceptions
By Tim Lloyd, May 14, 2010 4:31 pm
We use the ReSharper test runner here at GojiSoft to run NUnit tests
from within Visual Studio. It’s a great test runner, but doesn’t play
nicely with multi-threaded components where exceptions may occur on
non-test threads. Unhandled exceptions on non-test threads are hidden
and tests which should fail, instead pass.
...
The problem lies in the fact that the ReSharper test runner is
configured to behave in the same way as .Net 1.0 and 1.1 apps where
unhandled exceptions on non-main threads were swallowed. The situation
improves from .Net 2.0 where all unhandled exceptions flatten the
process. However, Microsoft had to allow existing .Net 1.0 and 1.1
apps the option of behaving as before on new .Net frameworks. They
introduced the app.config setting: legacyUnhandledExceptionPolicy.
The ReSharper test runner is configured by default to use the .Net 1.0
and 1.1 policy, so if there is an unhandled non-test thread exception
it does not bubble up and cause the test to fail – the test passes,
and we get a false positive instead.
If unhandled exceptions on non-test threads should fail tests, the
app.config for the ReSharper test runner has to be updated.
...
Turn the legacy unhandled exception policy off by editing legacyUnhandledExceptionPolicy: <legacyUnhandledExceptionPolicy enabled="0" />
Now multi-threaded tests fail as expected when they raise exceptions on non-test threads:
Buyer beware…
There is a caveat to this. Exceptions on non-test threads will now
flattened the test runner and test suite execution will be halted when
they happen. This is in contrast to normal test runs where failed
tests are marked as failed, and the test runner continues. ...
I just had the same problem, my solution is to catch the exception and increment an exception counter, so the Test method just have to assert the exception counter is 0 to confirm no thread got an exception.
An extract of my test code once specific environment stuff is removed:
const int MaxThreads = 25;
const int MaxWait = 10;
const int Iterations = 10;
private readonly Random random=new Random();
private static int startedThreads=MaxThreads ;
private static int exceptions = 0;
…
[Test]
public void testclass()
{
// Create n threads, each of them will be reading configuration while another one cleans up
Thread thread = new Thread(Method1)
{
IsBackground = true,
Name = "MyThread0"
};
thread.Start();
for (int i = 1; i < MaxThreads; i++)
{
thread = new Thread(Method2)
{
IsBackground = true,
Name = string.Format("MyThread{0}", i)
};
thread.Start();
}
// wait for all of them to finish
while (startedThreads > 0 && exceptions==0)
{
Thread.Sleep(MaxWait);
}
Assert.AreEqual(0, exceptions, "Expected no exceptions on threads");
}
private void Method1()
{
try
{
for (int i = 0; i < Iterations; i++)
{
// Stuff being tested
Thread.Sleep(random.Next(MaxWait));
}
}
catch (Exception exception)
{
Console.Out.WriteLine("Ërror in Method1 Thread {0}", exception);
exceptions++;
}
finally
{
startedThreads--;
}
}
private void Method2()
{
try
{
for (int i = 0; i < Iterations; i++)
{
// Stuff being tested
Thread.Sleep(random.Next(MaxWait));
}
}
catch (Exception exception)
{
Console.Out.WriteLine("Ërror in Method2 Thread {0}", exception);
exceptions++;
}
finally
{
startedThreads--;
}
}
I solved the problem by creating an addin for nunit, which "installs" an ITestDecorator.