Im trying to set text after all threads are finished.
Do you have any ideas for me?
fun threadStart(){
var ende = 150_000
val s = Semaphore(1)
var thread1 :Thread = Thread(Runnable{
while(counter < ende){
counter++
println("1. Thread : $counter")
println("${Thread.currentThread().name} 1. Thread $counter")
}
if(counter == ende) {
while (counter != 0) {
counter--
println("${Thread.currentThread().name} der Minus counter $counter")
s.release()
}
}
thread1.start()
thread2.start()
thread3.start()
thread4.start()
Normally I would write a print after thread4 here or in the main after threadstart()
Are you asking how to make the main thread wait for the other threads to finish? If so, you can do that with:
thread1.join()
thread2.join()
thread3.join()
thread4.join()
Related
I have come up with a pseudocode solution to the barbershop problem.
Requirements- a customer can call gethaircut() and a barber can call cuthair() and theres n seats available.
A barber should be sleeping until a customer calls gethaircut.
If n seats are taken then the customer should call balk() which just exits that customer thread.
The methods gethaircut and cuthair should be only running in parallel with one thread of each caller, meaning only one thread should be calling cuthair while another thread is calling gethaircut.
There is only one barber.
Here is the solution I came up with.. I really cannot format this correctly on the phone.. Please bear with
// Sem = semaphore. Sry Im on my phone
Int n = maxSeats
Sem mutex = new Sem(1)
Sem hairCutMutex = new Sem(1)
Sem canCutHair = new Sem(0)
Sem finishedHairCut = new Sem(0)
Customer() {
P(mutex)
if (n == 0) {
V(mutex)
balk();
}
V(mutex)
P(hairCutMutex)
getHairCut()
V(canCutHair)
P(finishedHairCut)
V(hairCutMutex)
P(mutex)
n++
V(mutex)
}
`Barber() {
while (true) {
P(canCutHair)
cutHair()
V(finishedHairCut)
}
}
`
I have situation where i have to Use Task.Run In my ForEach loop
Requirement:
I'm going to be forced to manually kill thread
I have button where i can start and stop this Thread or Task.Run in For loop.
Problem
My problem is when i start the Task.Run method Its running but when i try to stop with using CancellationTokenSource or runningTaskThread.Abort(); it will not kill. its just stop when i start new Task.Run at that time it run with old thread so it become multiple thread every start process.
Code:
Below is my code for start Thread
var messages = rootObject.MultiQData.Messages.Where(m => m.TimeStamp > DateTime.Now).OrderBy(x => x.TimeStamp).ToList();
//Simulate MultiQ file in BackGroud
if (messages.Count > 0)
{
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
Task.Factory.StartNew(
() =>
{
runningTaskThread = Thread.CurrentThread;
messages.ForEach(
m => SetUpTimer(m, rootObject.MultiQData.Connection.FleetNo));
}, cancellationToken);
}
For stop Task.Run
if (cancellationTokenSource != null)
{
if (cancellationToken.IsCancellationRequested)
return;
else
cancellationTokenSource.Cancel();
}
I have also use Thread with Thread.Abort but it is not working
Please Help to solve this issue
I got solution using timer.Stop(),timer.Dispose(). On creation of Thread i am calling SetUpTimer and this SetupTimer i have created multiple timer.
So on call of stop thread i have dispose timer and its work for me
For reference see below code
private void SetUpTimer(Message message, string fleetNo)
{
var ts = new MessageTimer();
var interval = (message.TimeStamp - DateTime.Now).TotalMilliseconds;
interval = interval <= 0 ? 100 : interval;
ts.MessageWrapper = new MessageWrapper(message, fleetNo);
ts.Interval = interval;
ts.Elapsed += ts_Elapsed;
ts.Start();
//Add timer in to the lost for disposing timer at time of stop Simulation
lsTimers.Add(ts);
}
private void StopTask()
{
try
{
// Attempt to cancel the task politely
if (cancellationTokenSource != null)
{
if (cancellationToken.IsCancellationRequested)
return;
else
cancellationTokenSource.Cancel();
}
//Stop All Timer
foreach (var timer in lsTimers)
{
timer.Stop();
timer.Dispose();
}
}
catch (Exception ex)
{
errorLogger.Error("Error while Stop simulation :", ex);
}
}
I am building a method that takes x-sized sequence of methods and returns the result of the first method to finish.
def invokeAny(work: Seq[() => Int]): Int = ???
How can I accomplish this by using Threads? (no futures allowed)
This is the best I have been able to come up with, but seems not to work in all circumstances.
def invokeAny(work: Seq[() => Int]): Int = {
#volatile var result = 0 // set to return value of any work function
val main = Thread.currentThread()
val threads: Seq[Thread] = work.map(work => new Thread( new Runnable {
def run { result = work(); main.interrupt(); }}))
threads.foreach(_.start())
for(thread <- threads) {
try {
thread.join()
} catch {
// We've been interrupted: finish
case e: InterruptedException => return result
}
}
return result
}
Not the pretiest answer, but seemed to work:
def invokeAny(work: Seq[() => Int]): Int = {
#volatile var result = 0 // set to return value of any work function
val main = Thread.currentThread()
var threads: Seq[Thread] = Seq()
//Interrupts all threads after one is interrupted
def interruptAll = {
main.interrupt()
for(thread <- threads) {
thread.interrupt()
}
}
threads = work.map(work => new Thread(
new Runnable {
def run {
result = try {
work() } catch {
case e:InterruptedException => return
}
interruptAll;
}
}))
threads.foreach(_.start())
for(thread <- threads) {
try {
thread.join()
} catch {
// We've been interrupted: finish
case e: InterruptedException => return result
}
}
return result
}
Using a BlockingQueue, no shared mutable state, worker threads write to a queue, the main threads wait till they finish and read from the queue then do something with the results like sum
def invokeAny1(work: Seq[() => Int]): Int = {
val queue = new ArrayBlockingQueue[Int](work.size)
val threads: Seq[Thread] = work.map(w => new Thread( new Runnable {
def run {
val result= w()
queue.put(result) }}))
threads.foreach(_.start())
threads.foreach(_.join())
var sum:Int=0
while(!queue.isEmpty) {
sum +=queue.take()
}
sum
}
Using a CountDownLatch.
Worker threads increment an atomic variable.
When all the threads are done the latch is released and the main thread can read the data from the atomic variable
def invokeAny2(work: Seq[() => Int]): Int = {
val total=new AtomicInteger
val latch= new CountDownLatch(work.size)
val threads: Seq[Thread] = work.map(w => new Thread( new Runnable {
def run {
val result= w()
total.getAndAdd(result)
latch.countDown
}}))
threads.foreach(_.start())
latch.await //wait till the latch is released
total.get
}
}
I'm having some problems in returning a value from a thread in perl.
The code I'm using is this:
use threads;
foreach $num(1 .. 100)
{
push(#threads, threads->create (\&readnum, $num));
sleep(1) while(scalar threads->list(threads::running) >= 10);
}
$_->join foreach #threads;
sub readnum {
# some code here
}
so I want to return a value from readnum i.e:
use threads;
foreach $num(1 .. 100)
{
if($ok)
{
push(#threads, threads->create (\&readnum, $num));
sleep(1) while(scalar threads->list(threads::running) >= 10);
}
}
$_->join foreach #threads;
sub readnum {
# some code here
return $ok ? "1" : "0";
}
So I want to check the value of $ok if it's true it'll create a new thread.
edit:
what i want is to check for $ok value, if it's true it'll creat a new thread and keep progress else it stop. the same idea without threads :
foreach $num(1 .. 100)
{
$ok = readnum($num);
print "runing\n";
die "stoped\n" if $ok eq 1;
}
sub readnum {
# some code here
$_[0]/5 eq 2 ? return 1 : return 0;
}
but with thread i can't put the returned value in $ok.
hope it's clear now. thanks
What you are trying to do is not return a value from a thread, but have one thread the ability to signal to the main thread that no more threads should be created. You can do that by creating a shared global. In the example below, there is a 1/20 chance that a random thread will decide that processing should be stopped.
There may be other, better ways of dealing with your specific problem (for example, each thread pushing results to a shared array, and the main thread checking how many results are there etc), but this seems to match your situation.
#!/usr/bin/env perl
use strict;
use warnings;
use threads;
use threads::shared;
my $KEEP_GOING :shared;
$KEEP_GOING = 1;
my #threads;
THREAD:
for my $num (1 .. 100) {
sleep 1 while threads->list(threads::running) >= 10;
{
lock $KEEP_GOING;
if($KEEP_GOING) {
push #threads, threads->create(\&readnum, $num);
}
else {
print "Won't create thread for $num .. Goodbye!\n";
last THREAD;
}
}
}
$_->join for #threads;
sub readnum {
my $num = shift;
printf "Thread id: %d\tnum = %d\n", threads->tid, $num;
sleep 1 + rand(3);
{
lock $KEEP_GOING;
if (0.05 > rand) {
$KEEP_GOING = 0;
}
}
}
Output:
Thread id: 1 num = 1
Thread id: 2 num = 2
Thread id: 3 num = 3
Thread id: 4 num = 4
Thread id: 5 num = 5
Thread id: 6 num = 6
Thread id: 7 num = 7
Thread id: 8 num = 8
Thread id: 9 num = 9
Thread id: 10 num = 10
Won't create thread for 11 .. Goodbye!
I have to implement a blocking and synchronized queue in scala.
If I don't miss something, synchronizing is pretty simple, but for my queue to be blocking I could only think of that (which works) :
def pop() : T = {
this.synchronized
{
_read()
if(_out.isEmpty) throw new Empty()
val ret = _out.head
_out = _out.tail
_length -= 1
return ret
}
}
def waitPop() : T =
{
var ret : Option[T] = None
// Possibly wait forever
while(ret.isEmpty)
{
try { ret = Some(pop) }
catch { case e : Empty => Thread.sleep(1000) }
}
ret.get
}
The problem here is Thread.sleep, it could compromise performance, couldn't it ?
Of course, putting a lower value would mean consuming more of the CPU.
Is there a way to wait properly ?
Thanks.
Thanks to Voo, I got what I needed :
def waitPop() : T =
{
this.synchronized
{
while(isEmpty) wait
pop
}
}
While in push, I added notifyAll (still in a synchronized block).
notify was also working, but with notifyAll the result appears less deterministic.
Thanks a lot !