Access Itcl Class Scope in Tcl Thread - multithreading

First of all, this is a follow up to a previous question of mine.
I would like to use threading in Tcl but in collaboration with Itcl.
Here is a sample:
package require Itcl
package require Thread
::itcl::class ThreadTest {
variable thread [thread::create {thread::wait}]
variable isRunning 0
method start {} {
set isRunning 1
thread::send $thread {
proc loop {} {
puts "thread running"
if { $isRunning } {
after 1000 loop
}
}
loop
}
}
method stop {} {
set isRunning 0
}
}
set t [ThreadTest \#auto]
$t start
vwait forever
However, when the condition statement tries to execute and check if the isRunning variable is true, I get a no such variable error. I understand that this is because a proc only has access to the global scope. However, in this situation, I would like to contain the variable local to the class.
Is there a way to accomplish this?

Tcl variables are per-interpreter, and interpreters are strongly bound to single threads (which greatly reduces the number of global-level locks required). To do what you want, you need to use a shared variable. Luckily, support for them is included with the Thread package (documentation here). You might then rewrite your code like this:
package require Itcl
package require Thread
::itcl::class ThreadTest {
variable thread [thread::create {thread::wait}]
constructor {} {
tsv::set isRunning $this 0
}
method start {} {
tsv::set isRunning $this 1
thread::send $thread {
proc loop {handle} {
puts "thread running"
if { [tsv::get isRunning $handle] } {
after 1000 loop $handle
}
}
}
thread::send $thread [list loop $this]
}
method stop {} {
tsv::set isRunning $this 0
}
}
set t [ThreadTest \#auto]
$t start
vwait forever

Related

How do I detect if thread/s is running

The following is a simple code example I'm working on. It just starts a thread, wait 5 seconds, and then terminate it.
#!/usr/bin/perl
use strict;
use warnings;
use threads;
sub thread_sub
{
threads->create(sub
{
sleep 5; # HERE A WHILE ROUTINEs EMULATED BY SLEEP
threads->detach();
});
}
thread_sub();
exit;
But the result is:
# ./multithread.pl
Perl exited with active threads:
1 running and unjoined
0 finished and unjoined
0 running and detached
This because it runs the thread but after that exit without waiting.
So, how can I wait for thread to finish before exit? I know there is is_running, but I don't known how to implement it in my code. Obliviously the reported code is just an example to understand how to implement is_running. Thank you.
To wait for a thread to finish, one typically uses the following:
$thread->join();
To wait for all threads, one would therefore use the following:
$_->join() for threads->list();
Don't detach the thread if this is what you are going to do.
About detach...
If you had fire-and-forget threads, you could use
use threads;
use threads::shared;
my $thread_count :shared = 0;
sub thread_sub {
{ lock $thread_count; ++$thread_count; cond_signal($thread_count); }
my $thread = async {
sleep 5;
{ lock $thread_count; --$thread_count; cond_signal($thread_count); }
};
$thread->detach(); # Free the small thread object as soon as it completes.
}
thread_sub();
# When it's time to exit:
{ lock($thread_count); cond_wait($thread_count) while $thread_count != 0; }
But that doesn't gain you much over just joining the threads, which is far simpler.
use threads;
sub thread_sub {
async {
sleep 5;
};
}
thread_sub();
# Periodically:
$_->join() for threads->list(threads::joinable);
# When it's time to exit:
$_->join() for threads->list();
Finally, it's more common in practice to create a pool of threads and reuse them rather then creating threads on the fly because thread creation is expensive in Perl. In this situation, detaching makes even less sense.
use threads;
use Thread::Queue qw( ); # 3.01+
use constant NUM_WORKERS => 3;
sub process_job { sleep 5 }
my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
async {
while (my $job = $q->dequeue()) {
process_job($job);
}
};
}
$q->enqueue('some_job');
# When it's time to exit:
$q->end();
$_->join() for threads->list();
I haven't used it, but look into Thread::Pool.
By the way, async { ... } is just a cleaner way of saying threads->create(sub { ... }).
Why are you doing this? Detaching a thread means that you don't care about its return or fate; it will finish and exit or be killed as the program is about to exit.
If you want to wait for it don't detach but join.
As for the question of how to use is_running, you need a thread object
use warnings;
use strict;
use feature 'say';
use threads;
$| = 1;
sub thread_sub
{
my $thr = threads->create(sub
{
## threads->detach();
sleep 2; say "\tprocessing ..";
sleep 2; say "\tdone";
});
return $thr;
}
my $thr = thread_sub();
while ($thr->is_running) { # or: while (threads->list)
sleep 1;
say "main";
}
$_->join for threads->list; # instead of detaching
say "done";
Btw, a detached thread is also covered by is_running (or list) and the above works for it as well. But doing that doesn't make sense; I am just discussing the method you ask about.

Java thread interruption won't work for me (in groovy)

Feeling stupid somehow as I'm now trying to get a simple interrupt for a thread working in groovy for some hours already.
Somehow following code won't set the 'interrupted' flag in the thread 'name'. Causing the loop to run 'til its end.
Found tons of other questions where usually the check for Thread.currentThread().isInterrupted() was missing. But this is not the case here:
def t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.currentThread().isInterrupted(); ++i) {
println "$i"
sleep 1000
}
} catch (InterruptedException e) {
println "Catched exception"
Thread.currentThread().interrupt();
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
sleep 2000
I get following output
Interrupting thread in 1...
0
Interrupting thread...
1
2
3
4
5
6
7
8
9
Wonder what I miss here / am doing wrong?
Tried also using ExecutorService and calling cancel(true) on the returned Future. Didn't work either.
If you interrupt the thread while sleeping, the sleeping interrupted thread catches the InterruptedException thrown by Thread.sleep and the interrupted status is cleared. So your Thread.currentThread().isInterrupted() always returns false.
You can make your code work if you replace sleep 1000 with Thread.sleep(1000).
TL;DR: Do not use Thread interruption as abort criterion, but use some custom flag instead.
You are not using Thread.sleep() which would throw InterruptedException, but GDKs Object.sleep() which handles and ignores interruptions: http://docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/lang/Object.html#sleep(long)
Either use Thread.sleep() instead like: (interrupting in the catch block is useless in your case)
def t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
println i
Thread.sleep 1000
}
} catch (InterruptedException e) {
println "Catched exception"
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
Or use the variant of Object.sleep() with a Closure and abort your loop in there, e. g. by throwing InterruptedException like:
def t
t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
println i
sleep(1000) {
throw new InterruptedException()
}
}
} catch (InterruptedException e) {
println "Catched exception"
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
Having solved your confusion, now let me advice not to do what you are trying to do. Interrupting is any no way a good method for usage as abort condition. A sleep or blocking IO can always be interrupted due to various reasons. The much better approach is to make your run-loop check some boolean flag that you toggle to abort the work.

c++: How to quit a multi-threading program properly

In my c++11 project, I need to generate two threads which run infinitely. Here is an example:
static vector<int> vec;
static std::mutex mtx;
static std::condition_variable cond;
static bool done = false;
void f1()
{
while(!done)
{
// do something with vec and mtx
}
}
void f2()
{
while(!done)
{
// do something with vec and mtx
}
}
thread t1(f1);
thread t2(f2);
void finish(int s)
{
done = true;
// what should I do???
}
int main()
{
signal(SIGINT, finish);
t1.join();
t2.join();
return 0;
}
Normally, I won't stop or kill this program. But in case of exception, I think I need to do something for ctrl-c, which is used to kill the program. But I don't know how to quit this program properly.
If I'm right, t1 and t2 might continue executing even if the main has returned 0. So I think I need to make them detach like this:
void finish()
{
done = true;
t1.detach();
t2.detach();
}
However, when I execute the program and do ctrl-c, I get an error:
terminate called after throwing an instance of 'std::system_error'
I've found this link, so I think the problem is the same: mtx and/or cond has been destroyed while t1 or t2 hasn't finished yet.
So how could I kill the program properly? Or I don't need to deal with the signal ctrl-c and the program itself knows what to do to quit properly?
done should be std::atomic<bool>, or unsequenced reads/writes are not legal.
Accessing atomic variables is only safe in a signal handler if std::atomic<bool>::is_lock_free is true. Check that. If it isn't true, your program should probably abort with an error in main.
When you .join(), you wait for the thread to finish executing. And you don't want to exit main unless the threads have finished.
In short, do this:
static std::atomic<bool> done = false;
(rest of code goes here)
int main()
{
if (!done.is_lock_free()) return 10; // error
signal(SIGINT, finish);
t1.join();
t2.join();
}

C++/Cli synchronizing threads writing to file

I am trying to synchronize threads writing data to a text file in a class by using Monitor, but in my code it seems that the else statement is never evaluated, is this the correct use of monitor for thread synchronization?
void Bank::updatefile()
{
Thread^ current = Thread::CurrentThread;
bool open = false;
current->Sleep(1000);
while (!open)
{
if (Monitor::TryEnter(current))
{
String^ fileName = "accountdata.txt";
StreamWriter^ sw = gcnew StreamWriter(fileName);
for (int x = 0; x < 19; x++)
sw->WriteLine(accountData[x]);
sw->Close();
Monitor::Pulse;
Monitor::Exit(current);
current->Sleep(500);
open = true;
}
else
{
Monitor::Wait(current);
current->Sleep(500);
}
}
}
You're passing an object to Monitor::TryEnter that is specific to the thread in which it is executing (i.e. Thread^ current = Thread::CurrentThread;). No other threads are using the same object (they're using the one for their own thread). So there's never a collision or locking conflict.
Try creating some generic object that's shared among the threads, something higher up in the Bank class. Then use that for your TryEnter call.
Your use of Monitor is partially correct. The object you're using for locking is not correct.
Monitor
Monitor::Pulse is unnecessary here. Just Exit the monitor, and the next thread will be able to grab the lock.
Monitor::Wait is incorrect here: Wait is supposed to be used when the thread has the object already locked. Here, you have the object not locked yet.
In general, Pulse and Wait are rarely used. For locking for exclusive access to a shared resource, Enter, TryEnter, and Exit are all you need.
Here's how your use of Monitor should be written:
Object^ lockObj = ...;
bool done = false;
while(!done)
{
if(Monitor::TryEnter(lockObj, 500)) // wait 500 millis for the lock.
{
try
{
// do work
done = true;
}
finally
{
Monitor::Exit(lockObj);
}
}
else
{
// Check some other exit condition?
}
}
or if the else is empty, you can simplify it like this:
Object^ lockObj = ...;
Monitor::Enter(lockObj); // Wait forever for the lock.
try
{
// do work
}
finally
{
Monitor::Exit(lockObj);
}
There is a class that Microsoft provides that makes this all easier: msclr::lock. This class, used without the ^, makes use of the destructor to release the lock, without a try-finally block.
#include <msclr\lock.h>
bool done = false;
while(!done)
{
msclr::lock lock(lockObj, lock_later);
if (lock.try_acquire(500)) // wait 500 millis for the lock to be available.
{
// Do work
done = true;
}
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
{
msclr::lock lock(lockObj); // wait forever for the lock to be available.
// Do work
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
The object to lock on
Thread::CurrentThread is going to return a different object on each thread. Therefore, each thread attempts to lock on a different object, and that's why all of them succeed. Instead, have one object, created before you spawn your threads, that is used for locking.
Also, instead of opening & closing the file on each thread, it would be more efficient to open it once, before the threads are spawned, and then just use that one StreamWriter from each of the threads. This also gives you a obvious object to lock on: You can pass the StreamWriter itself to Monitor::Enter or msclr::lock.

Perl: Error handling threads

sub worker {
exit 1;
}
my $thr = threads->create(\&worker);
while ($thr->is_running()) {
print "running\n";
}
my $rc = $thr->join();
exit $rc;
I come from Python. Is there something similar to try/except that I can use around while($thr->is_running)
I get (because I exit 1 in worker):
Perl exited with active threads:
0 running and unjoined
1 finished and unjoined
0 running and detached
I want to be able to catch the exit or other compiliation error worker might have
use strict;
use warnings;
use threads;
sub worker {
my $bad = 1/0;
}
my $thr = threads->create( \&worker );
while ( $thr->is_running() ) {
sleep 1;
}
my $rc = $thr->join(); #NB - RC will be 'undef' because there's no return.
OUTPUT:
Thread 1 terminated abnormally: Illegal division by zero at mythread.pl line 6.
Is it possible to catch it the error? and how and where?
Don't call exit in your thread. That exits your whole program. threads -> exit is what you want.
http://perldoc.perl.org/threads.html#EXITING-A-THREAD
threads->exit()
If needed, a thread can be exited at any time by calling threads->exit() . This will cause the thread to return undef in a scalar context, or the empty list in a list context.
When called from the main thread, this behaves the same as exit(0).
join waits for the thread to complete.
Don't use $a. It's a bad variable name anyway, but it's also used for perl sort.
You're capturing $rc but that implies a return in your thread. As it, it'll be undefined.
But this will work:
use strict;
use warnings;
use threads;
sub worker {
sleep 10;
threads->exit;
}
my $thr = threads->create( \&worker );
while ( $thr->is_running() ) {
print $thr ->tid, " running\n";
sleep 1;
}
print $thr ->tid, " not running\n";
sleep 5;
my $rc = $thr->join(); #NB - RC will be 'undef' because there's no return.
In the latter case, $rc is undef because you exited. You can test for it being undefined if you want to trap an abnormal exit. (Just make sure you do actually return something on a success).
Alternatively, wrap your code in the thread with an eval because that won't be a fatal error. Doesn't come up too often, but I'd suggest rather than trying to capture the broad spectrum of possible fatal errors, you're far better off just testing whether it completed successfully instead.
To answer your second question - something like this:
use strict;
use warnings;
use threads;
sub worker {
sleep 5;
my $fatal = 1 / 0;
return 1;
}
sub otherworker {
sleep 4;
eval { my $fatal = 1 / 0; };
if ($#) { return $# }
else { return "No error" }
}
my $thr = threads->create( \&worker );
my $thr2 = threads->create( \&otherworker );
while ( $thr->is_running() ) {
print $thr ->tid, " running\n";
sleep 1;
}
print $thr ->tid, " not running\n";
foreach my $thread ( threads->list ) {
my $return_code = $thread->join;
if ( not defined $return_code ) {
print $thread ->tid(), ": terminated abnormally\n";
}
else {
print $thread ->tid, ": exited with $return_code \n";
}
}

Resources