class Program
{
static void Main(string[] args)
{
ParameterizedThreadStart aStart = new ParameterizedThreadStart(Addition);
Thread aThread = new Thread(aStart);
Data aData = new Data();
aData.X = 10;
aData.Y = 20;
aThread.Start(aData);
aThread.Join();
Console.WriteLine("End of the program");
}
static void Addition(object data)
{
var a = data as Data;
var b = a.X + a.Y;
a.result = b;
Console.WriteLine(a.result);
Thread.Sleep(1000);
Console.WriteLine("End of thread");
}
}
I have written an example to understand the Join method();
Can any body explain how it works ? and what is the difference between sleep and join()
Thread.Sleep
Blocks the current thread for the specified number of milliseconds.
-Thread.Join
Blocks the calling thread until a thread terminates (you don't know for how long)
Note that the Thread.Join() method only blocks the calling thread (usually the application's main thread of execution) until your thread object completes. You can still have other threads executing in the background while waiting for your specific Thread to finish executing.
http://msdn.microsoft.com/en-us/library/system.threading.thread.join.aspx
Join waits until the thread you've called it on stops. Sleep sleeps for a given time period.
It causes the currently running thread to stop execution till the time the thread it joins with stop execution.i.e joins method waits for a thread to die.
Related
My Environment: C++ Builder XE4.
I am using Mutex. In the following code, I expect that while Timer1 would acquire mutex, Timer2 process would be skipped. However, Timer2 process was not skipped at all.
What is the problem in the code?
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
String MutexName = L"Project1";
HANDLE HWNDMutex;
void __fastcall TForm1::FormShow(TObject *Sender)
{
HWNDMutex = CreateMutex(NULL, false, MutexName.c_str());
if (HWNDMutex == NULL) {
String msg = L"failed to create mutex";
OutputDebugString(msg.c_str());
}
Timer1->Enabled = false;
Timer1->Interval = 1000; // msec
Timer1->Enabled = true;
Timer2->Enabled = false;
Timer2->Interval = 200; // msec
Timer2->Enabled = true;
}
__fastcall TForm1::~TForm1()
{
CloseHandle(HWNDMutex);
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (WaitForSingleObject(HWNDMutex, INFINITE) == WAIT_TIMEOUT) {
return;
}
if (CHK_update->Checked) {
String msg = L"Timer1 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
Memo1->Lines->Add(msg);
}
for(int loop=0; loop<10; loop++) {
Application->ProcessMessages();
Sleep(90); // msec
}
ReleaseMutex(HWNDMutex);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
if (WaitForSingleObject(HWNDMutex, INFINITE) == WAIT_TIMEOUT) {
return;
}
if (CHK_update->Checked) {
String msg = L">>>Timer2 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
Memo1->Lines->Add(msg);
}
ReleaseMutex(HWNDMutex);
}
//---------------------------------------------------------------------------
Result
Timer1 2017/11/08 15:20:39.781
>>>Timer2 2017/11/08 15:20:39.786
>>>Timer2 2017/11/08 15:20:40.058
>>>Timer2 2017/11/08 15:20:40.241
>>>Timer2 2017/11/08 15:20:40.423
>>>Timer2 2017/11/08 15:20:40.603
Timer1 2017/11/08 15:20:40.796
>>>Timer2 2017/11/08 15:20:40.799
>>>Timer2 2017/11/08 15:20:41.071
>>>Timer2 2017/11/08 15:20:41.254
>>>Timer2 2017/11/08 15:20:41.436
>>>Timer2 2017/11/08 15:20:41.619
Timer1 2017/11/08 15:20:41.810
>>>Timer2 2017/11/08 15:20:41.811
>>>Timer2 2017/11/08 15:20:42.083
>>>Timer2 2017/11/08 15:20:42.265
>>>Timer2 2017/11/08 15:20:42.448
>>>Timer2 2017/11/08 15:20:42.633
I tried using TMutex with acquire() and release(), but it did not work either.
A mutex has a thread affinity and thus is re-entrant:
A mutex object is a synchronization object whose state is set to signaled when it is not owned by any thread, and nonsignaled when it is owned. Only one thread at a time can own a mutex object, whose name comes from the fact that it is useful in coordinating mutually exclusive access to a shared resource. For example, to prevent two threads from writing to shared memory at the same time, each thread waits for ownership of a mutex object before executing the code that accesses the memory. After writing to the shared memory, the thread releases the mutex object.
...
After a thread obtains ownership of a mutex, it can specify the same mutex in repeated calls to the wait-functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.
TTimer is a message-based timer. You have two timers running in the same thread. Which means their OnTimer events are serialized by default in relation to each other. Only one event can be running at a time (unless you do something stupid like call Application->ProcessMessages(), which is a re-entrant nightmare).
Timer2 will trigger first (4-5 times, actually), acquiring and releasing the mutex lock each time, before Timer1 triggers. Then Timer1 triggers, acquires the lock, runs a loop to pump the main UI message queue, thus allowing Timer2 to trigger again (multiple times) while Timer1Timer() is still running. Timer2 will re-acquire and release the same lock that the UI thread already has, so WaitForSingleObject() exits with WAIT_OBJECT_0 immediately. Then the loop ends and Timer1 releases the lock.
Your mutex is useless in this code. A mutex is meant for inter-thread synchronization, but you have no worker threads in this code! You have a single thread synchronizing against itself, which is redundant, and exactly the kind of deadlock-causing situation that many synchronization objects avoid by supporting re-entry.
A critical section also has a thread affinity and is re-entrant, so that is not going to help you, either:
A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used only by the threads of a single process.
...
When a thread owns a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. To release its ownership, the thread must call LeaveCriticalSection one time for each time that it entered the critical section. There is no guarantee about the order in which waiting threads will acquire ownership of the critical section.
However, a semaphore would work for what you are attempting, as it does not have a thread affinity:
A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. The count is decremented each time a thread completes a wait for the semaphore object and incremented each time a thread releases the semaphore. When the count reaches zero, no more threads can successfully wait for the semaphore object state to become signaled. The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.
The semaphore object is useful in controlling a shared resource that can support a limited number of users. It acts as a gate that limits the number of threads sharing the resource to a specified maximum number. For example, an application might place a limit on the number of windows that it creates. It uses a semaphore with a maximum count equal to the window limit, decrementing the count whenever a window is created and incrementing it whenever a window is closed. The application specifies the semaphore object in call to one of the wait functions before each window is created. When the count is zero—indicating that the window limit has been reached—the wait function blocks execution of the window-creation code.
...
A thread that owns a mutex object can wait repeatedly for the same mutex object to become signaled without its execution becoming blocked. A thread that waits repeatedly for the same semaphore object, however, decrements the semaphore's count each time a wait operation is completed; the thread is blocked when the count gets to zero. Similarly, only the thread that owns a mutex can successfully call the ReleaseMutex function, though any thread can use ReleaseSemaphore to increase the count of a semaphore object.
If you switch to a semaphore, your code as shown would deadlock itself as soon as Application->ProcessMessages() is called and the semaphore counter drops to 0, because of your use of INFINITE timeouts. So use smaller timeouts to prevent that.
Try this:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
HANDLE hSemaphore;
void __fastcall TForm1::FormShow(TObject *Sender)
{
hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
if (hSemaphore == NULL) {
OutputDebugString(L"failed to create semaphore");
}
Timer1->Enabled = false;
Timer1->Interval = 1000; // msec
Timer1->Enabled = true;
Timer2->Enabled = false;
Timer2->Interval = 200; // msec
Timer2->Enabled = true;
}
__fastcall TForm1::~TForm1()
{
if (hSemaphore)
CloseHandle(hSemaphore);
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
return;
}
if (CHK_update->Checked) {
String msg = L"Timer1 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
Memo1->Lines->Add(msg);
}
for(int loop=0; loop<10; loop++) {
Application->ProcessMessages();
Sleep(90); // msec
}
ReleaseSemaphore(hSemaphore, 1, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
return;
}
if (CHK_update->Checked) {
String msg = L">>>Timer2 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
Memo1->Lines->Add(msg);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
}
//---------------------------------------------------------------------------
On a side note: beware of giving a kernel-based synchronization object a name. That allows other processes to access it and mess around with its state behind your back. Don't name objects that you don't intend to share across process boundaries! Mutexes and semaphores are namable objects.
I am wondering how to shutdown JeroMQ properly, so far I know three methods that all have their pro and cons and I have no clue which one is the best.
The situation:
Thread A: owns context, shall provide start/stop methods
Thread B: actual listener thread
My current method:
Thread A
static ZContext CONTEXT = new ZContext();
Thread thread;
public void start() {
thread = new Thread(new B()).start();
}
public void stop() {
thread.stopping = true;
thread.join();
}
Thread B
boolean stopping = false;
ZMQ.Socket socket;
public void run() {
socket = CONTEXT.createSocket(ROUTER);
... // socket setup
socket.setReceiveTimeout(10);
while (!stopping) {
socket.recv();
}
if (NUM_SOCKETS >= 1) {
CONTEXT.destroySocket(socket);
} else {
CONTEXT.destroy();
}
}
This works just great. 10ms to shutdown is no problem for me, but I will unnecessarily increase the CPU load when there are no messages received. At the moment I prefer this one.
The second method shares the socket between the two threads:
Thread A
static ZContext CONTEXT = new ZContext();
ZMQ.Socket socket;
Thread thread;
public void start() {
socket = CONTEXT.createSocket(ROUTER);
... // socket setup
thread = new Thread(new B(socket)).start();
}
public void stop() {
thread.stopping = true;
CONTEXT.destroySocket(socket);
}
Thread B
boolean stopping = false;
ZMQ.Socket socket;
public void run() {
try {
while (!stopping) {
socket.recv();
}
} catch (ClosedSelection) {
// socket closed by A
socket = null;
}
if (socket != null) {
// close socket myself
if (NUM_SOCKETS >= 1) {
CONTEXT.destroySocket(socket);
} else {
CONTEXT.destroy();
}
}
}
Works like a charm, too, but even if recv is already blocking the exception does not get thrown sometimes. If I wait one millisecond after I started thread A the exception is always thrown. I don't know if this is a bug or just an effect of my misuse, as I share the socket.
"revite" asked this question before (https://github.com/zeromq/jeromq/issues/116) and got an answer which is the third solution:
https://github.com/zeromq/jeromq/blob/master/src/test/java/guide/interrupt.java
Summary:
They call ctx.term() and interrupt the thread blocking in socket.recv().
This works fine, but I do not want to terminate my whole context, but just this single socket. I would have to use one context per socket, so I were not able to use inproc.
Summary
At the moment I have no clue how to get thread B out of its blocking state other than using timeouts, share the socket or terminate the whole context.
What is the correct way of doing this?
It is often mentioned that you can just destroy the zmq context and anything sharing that context will exit, however this creates a nightmare because your exiting code has to do its best in avoiding a minefield of accidentally calling into dead socket objects.
Attempting to close the socket doesn't work either because they are not thread safe and you'll end up with crashes.
ANSWER: The best way is to do as the ZeroMQ guide suggests for any use via multiple threads; use zmq sockets and not thread mutexes/locks/etc. Set up an additional listener socket that you'll connect&send something to on shutdown, and your run() should used a JeroMQ Poller to check which of your two sockets receive anything - if the additional socket receives something then exit.
Old question, but just in case...
I'd recommend checking out ZThread source. You should be able to create an instance of IAttachedRunnable that you can pass to the fork method, and the run method of your instance will be passed a PAIR socket and execute in another thread, while the fork will return the connected PAIR socket to use for communicating with the PAIR socket that your IAttachedRunnable got.
Check out the jeromq source here, even when you're doing a "blocking" recv, you're still burning CPU the entire time (the thread never sleeps). If you're worried about that, have the second thread sleep between polling and let the parent thread interrupt. Something like (just the relevant portions):
Thread A
public void stop() {
thread.interrupt();
thread.join();
}
Thread B
while (!Thread.interrupted()) {
socket.recv(); // do whatever
try {
Thread.sleep(10); //milliseconds
} catch (InterruptedException e) {
break;
}
}
Also, with regard to your second solution, in general you should not share sockets between threads - the zeromq guide is pretty clear on this - "Don't share ØMQ sockets between threads. ØMQ sockets are not threadsafe." Remember that a major use for ZMQ is IPC - threads communicating through connected sockets, not sharing the same end of one socket. No need for things like shared boolean stop variables.
I've got a boost::asio based thread pool running on N threads.
It used mainly for IO tasks (DB data storing/retreival). It also launches self-diagnostic timer job to check how 'busy' pool is (calculates ms diff between 'time added' and 'time handler called')
So the question is - is there any way to stop M of N threads ( for cases when load is very low and pool does not need so many threads).
When the load is high (determined by diagnostic task) then new thread is added:
_workers.emplace_back(srv::unique_ptr<srv::thread>(new srv::thread([this]
{
_service.run();
})));
(srv namespace is used to switch quickly between boost and std)
But when 'peak load' is passed I need some way to stop additional threads. Is there any solution for this?
What you are looking for is a way to interrupt a thread that is waiting on the io_service. You can implement some sort of interruption mechanism using exceptions.
class worker_interrupted : public std::runtime_error
{
public:
worker_interrupted()
: runtime_error("thread interrupted") {}
};
_workers.emplace_back(srv::unique_ptr<srv::thread>(new srv::thread([this]
{
try
{
_service.run();
}
catch (const worker_interrupted& intrruption)
{
// thread function exits gracefully.
}
})));
You could then just use io_service::post to enqueue a completion handler which just throws worker_interrupted exception.
I am using Windows ThreadPools in my application, and am experiencing a memory leak of 136 bytes for every call to CreateThreadPoolWork(), as seen via UMDH:
+ 1257728 ( 1286424 - 28696) 9459 allocs BackTraceB0035CC
+ 9248 ( 9459 - 211) BackTraceB0035CC allocations
ntdll!RtlUlonglongByteSwap+B52
ntdll!TpAllocWork+8D
KERNEL32!CreateThreadpoolWork+25
... My Code ...
I am using Cleanup Group, so per the documentation I am not calling CloseThreadPoolWork().
My code for handling the ThreadPool is:
typedef PTP_WORK ThreadHandle_t;
typedef PTP_WORK_CALLBACK THREAD_ENTRY_POINT_T;
static PTP_POOL pool = NULL;
static TP_CALLBACK_ENVIRON CallBackEnviron;
static PTP_CLEANUP_GROUP cleanupgroup = NULL;
int mtInitialize()
{
InitializeThreadpoolEnvironment(&CallBackEnviron);
pool = CreateThreadpool(NULL);
if (NULL == pool)
{
return -1;
}
cleanupgroup = CreateThreadpoolCleanupGroup();
if (NULL == cleanupgroup)
{
return -1;
}
SetThreadpoolCallbackPool(&CallBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL);
return 0; // Success
}
void mtDestroy()
{
CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL);
CloseThreadpoolCleanupGroup(cleanupgroup);
DestroyThreadpoolEnvironment(&CallBackEnviron);
CloseThreadpool(pool);
}
//Create thread
ThreadHandle_t mtRunThread(THREAD_ENTRY_POINT_T entry_point, void *thread_args)
{
PTP_WORK work = NULL;
work = CreateThreadpoolWork(entry_point, thread_args, &CallBackEnviron);
if (NULL == work) {
// CreateThreadpoolWork() failed.
return 0;
}
SubmitThreadpoolWork(work);
return work;
}
//Wait for a thread to finish
void mtWaitForThread(ThreadHandle_t thread)
{
WaitForThreadpoolWorkCallbacks(thread, FALSE);
}
Am I doing something wrong?
Any ideas why I'm leaking memory?
I'm guessing you figured it out, given your comment, but the problem is that you only call CloseThreadpoolCleanupGroupMembers() in mtDestroy().
If you have a persistent thread pool the memory will not be freed unless you call CloseThreadpoolCleanupGroupMembers() periodically. Your code and comments suggests that you do, though I can't confirm this without the code responsible for creating and destroying your thread pool.
My recommendation for persistent thread pools is to just call CloseThreadpoolWork() in the callback functions. Microsoft's recommendations work better if you're creating and destroying thread pools, but CloseThreadpoolWork() is simpler and easier than periodically calling CloseThreadpoolCleanupGroupMembers() if you're maintaining one thread pool for the life of your application.
By the way, it's safe to do both as long as you tell CloseThreadpoolCleanupGroupMembers() to cancel any pending callbacks (pass fCancelPendingCallbacks as TRUE) to ensure CloseThreadpoolWork() is called on any cleaned up work items:
You can revoke the work object’s membership only by closing it, which
can be done on an individual basis with the CloseThreadpoolWork
function. The thread pool knows that the work object is a member of
the cleanup group and revokes its membership before closing it. This
ensures that the application doesn’t crash when the cleanup group
later attempts to close all of its members. The inverse isn’t true: If
you first instruct the cleanup group to close all of its members and
then call CloseThreadpoolWork on the now invalid work object, your
application will crash.
From Windows with C++ - Thread Pool Cancellation and Cleanup
I have run a secondary thread which some operations are carried on. Then while executing in secondary thread i want to call some operations on main thread. Can any one have sample code for it. I could not find it from google.
Here is my sample call:
Glib::thread_init();
Glib::Thread *const myThread = Glib::Thread::create(sigc::mem_fun(*this, &MyClass::MyFunction), true);
myThread->join();
MyClass::MyFunction()
{
//here i want to call the function from main thread
AnotherFunction();
}
MyClass::AnotherFunction()
{
}