So, we're trying to debug a problem with an app of ours and we think we've narrowed it down to a threading issue.
I understand based on Ruby's documentation on Thread that providing an integer argument to the join method specifies how long it will wait for the thread to join up before just returning nil.
However, I'm not sure what happens when you pass in '0.'
One of my colleagues, after digging around in the C code for the Ruby interpreter, seems to think that it's not "don't wait at all just join it immediately and return nil if it doesn't come back" and is more along the lines of "don't bother joining and just return a snapshot of the thread at the given moment."
Can anyone point me to some documentation on (or just flat out tell me) what passing a '0' argument to join() does?
After testing the code by Diego Basch:
def f()
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0)
end
def g()
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0.0000000000001)
end
def h()
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0.15)
end
f and g are very similar.
The reason for this is that f is just the limit -- put in as small of a number as possible.
And they mean the same thing. Check virtually immediately to see if the thread is done. When it isn't, return nil.
Thus in the code above, the until repeatedly evaluates in the first 2 cases but only evaluates a couple of times in the third case (in particular, every 0.15 seconds). Using 0 as a parameter functions exactly like every other number -- check to see if the thread is done in the next 0 seconds (now) and if it isn't return nil.
I'm afraid your colleague is not correct.
Your colleague is correct. Try this code for example:
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0)
and compare with:
y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}
puts "Waiting" until y.join(0.15)
See the documentation for join
Related
I have a problem with this script:
local plight = script.Parent.Bulb.PointLight
local slight = script.Parent.Bulb.SpotLight
local rotatingPart = script.Parent.Bulb
local reader = script.Parent.Parent["card-reader1a"].reader1a.ProximityPrompt
local c = 0
local cc = 0
local tweenService = game:GetService("TweenService")
local tInfo = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false)
local function rotating()
if c == 0 then
c = 1
local play1 = tweenService:Create(rotatingPart, tInfo, {CFrame = rotatingPart.CFrame * CFrame.Angles(0, math.rad(120), 0)})
play1:Play()
play1.Completed:Connect(rotating)
c = 0
end
end
reader.Triggered:Connect(rotating)
I have infinitive loop and I don't know how to stop it. I tried many methods and nothing worked. Can someone help?
Try removing
play1.completed:Connect(rotating)
This line of code means that upon the tween's completion fire the rotating function. Effectively causing an infinite loop.
Additionally since :Connect() a signal doesn't yield, every time rotating is called, c is set from 1 to 0 almost instantaneously. Which allows all calls to pretty much bypass the debounce.
If you wish to wait until the tween is complete, try using
play1.completed:Wait()
I made a function with a while loop that countdown from a specific time and returns when Time is up.
But I want to make a function get_time() that tells me how much time is left on the timer while the other is running.
This second function is also a while loop that waits for my input to return where the countdown is at now.
So how can I make this get_time() function?
Look at the following code (python) as reference
from multiprocessing import Process
def func1():
print 'func1: starting'
for i in xrange(10000000): pass
print 'func1: finishing'
def get_time():
print 'get_time: starting'
for i in xrange(10000000): pass
print 'get_time: finishing'
if __name__ == '__main__':
p1 = Process(target=func1)
p1.start()
p2 = Process(target=get_time)
p2.start()
p1.join()
p2.join()
I am just learning Perl as a fourth language.
My wish is to use Parallel::ForkManager to speed up a foreach loop using an array whose members are taken from a text file.
Basically I am testing a .txt file of URLs, and wish to make it so that it will test multiple members of the array at once, not one at a time (five at a time in this instance) and without spamming the same URL inadvertently DoSing it.
Would something like this do the trick?
$limit = new Parallel::ForkManager(5);
foreach (#lines) {
$limit->start and next;
$lines = $_;
... do processing here ...
$limit->finish;
}
or would it be the equivalent of running that loop 5 times making a small multithreaded DoS script?
It isn't too clear from the documentation, but
A call to start will block in the parent process until there are fewer children running than the limit specified. Then it will return the (non-zero) child PID in the parent, and zero in the child
A child process can see all the data in the parent process as it was when the start was called. The data is presumably copy-on-write, as the child may modify it but the changes aren't reflected in any other process's workspace
The $pm->start and next idiom may seem a little obscure. Essentially it skips the rest of the loop if the start method returns a true value. I prefer something like my $pid = $fm->start; next if $pid; or the if construct in the code below. Both do the same thing, but I think more legibly
I recommend that you experiment with this simpler application, which uses a cache of five child threads to print the numbers from zero to nine.
use strict;
use warnings;
use Parallel::ForkManager;
STDOUT->autoflush;
my $fm = Parallel::ForkManager->new(5);
for my $i (0 .. 9) {
my $pid = $fm->start;
if ($pid == 0) {
print "$i\n";
sleep 2;
$fm->finish;
}
}
To test, use a safe local process like print or write to avoid spamming the URL's. Here's a working snippet from a program I wrote that uses the fork manager.
my $pm=new Parallel::ForkManager(20);
foreach $add (#adds){
$pm->start and next;
#if email is invalid move on
if (!defined(Email::Valid::Loose->address($add))){
writeaddr(*BADADDR, $add); #address is bad
$pm->finish;
}
#if email is valid get domain name
$is_valid = Email::Valid::Loose->address($add);
if ($is_valid =~ m/\#(.*)$/) {
$host = $1;
}
$is_valid="";
# perform dsn lookup to check domain
#mx=mx($resolver, $host);
if (#mx) {
writeaddr(*GOODADDR, $add); #address is good
}else{
writeaddr(*BADADDR, $add); #address is bad
}
$pm->finish;
}
I just started learning Haskell, but the absence of loops is infinitely frustrating right now. I figured out how to write loops for functions. My problem, however, is that I want to output some results while iterating the loop. It seems that I have to use debug to perform this simple task.
So right now I would just appreciate an example of how to print out a string 10 times in the main structure.
In other words, I want to do this 10 times:
main = do
putStrLn "a string"
Thanks. I feel this will be very illuminating for my task.
You could define a recursive function that prints "a string" n times (n being the parameter of the function), like this:
printStringNTimes 0 = return ()
printStringNTimes n =
do
putStrLn "a string"
printStringNTimes (n-1)
main = printStringNTimes 10
A somewhat more general approach would be to define a function that repeats any IO action n times:
repeatNTimes 0 _ = return ()
repeatNTimes n action =
do
action
repeatNTimes (n-1) action
main = repeatNTimes 10 (putStrLn "a string")
The above function already exists in Control.Monad under the name replicateM_.
Well Haskell's IO is a bit tricky when you're just starting out since it's based on monads.
Your problem though has a simple solution:
main = replicateM_ 10 $ putStrLn "a string"
This is using the combinator replicateM_ from Control.Monad
It has lots of useful functions for composing and executing monadic actions.
I am also a beginner of Haskell, and I have a solution that is less elegant and yet is pragmatically useful.
main = do
putStr result
where
string = "a string"
result = concat [string ++ "\n" | i <- [1,2..10]]
So here, we have defined a list, the elements of which are the strings that you want to print out followed by a new line character.
I think the most imperative looking form of doing a for loop is:
for list action = mapM_ action list
main :: IO Int
main = do
for [0..10] (\ i -> do
print(i^2)
)
return 0
This actually looks pretty much like C code to me.
Doing something like to this allows you to loop a specific function, making it more reusable (instead of writing it out for each new thing you want to loop).
loop :: Int -> (IO()) -> IO()
loop 0 _ = return ()
loop n f =
do
f
loop (n - 1) f
Examples:
main = do
loop 5 (do
putStr "hello "
putStrLn "there")
main = do
loop 3 (do
loop 4 (putStrLn "Hi")
putStrLn ""
)
my solution:
n = 10
doSomething () = putStrLn "a string"
main = sequence (replicate n (doSomething()))
sequence: sequentially solve each IO a in a list
replicate n ele: build a list which repeats ele for n times, like take n (repeat ele)
I am trying loop over an array and return a value as shown below. But this gives me an error on the line after the if statement. It says "This expression was expected to have type unit but has type int"
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
for i = inputBits.Length - 1 to 0 do
if inputBits.[i] then
i
done
How would I do this? I am in the middle of recoding this with a recursive loop, as it seems to be the more accepted way of doing such loops in functional languages, but I still want to know what I was doing wrong above.
for loops are not supposed to return values, they only do an operation a fixed number of times then return () (unit). If you want to iterate and finally return something, you may :
have outside the loop a reference where you put the final result when you get it, then after the loop return the reference content
use a recursive function directly
use a higher-order function that will encapsulate the traversal for you, and let you concentrate on the application logic
The higher-function is nice if your data structure supports it. Simple traversal functions such as fold_left, however, don't support stopping the iteration prematurely. If you wish to support this (and clearly it would be interesting in your use case), you must use a traversal with premature exit support. For easy functions such as yours, a simple recursive function is probably the simplest.
In F# it should also be possible to write your function in imperative style, using yield to turn it into a generator, then finally forcing the generator to get the result. This could be seen as a counterpart of the OCaml technique of using an exception to jump out of the loop.
Edit: A nice solution to avoid the "premature stop" questions is to use a lazy intermediate data structure, which will only be built up to the first satisfying result. This is elegant and good scripting style, but still less efficient than direct exit support or simple recursion. I guess it depends on your needs; is this function to be used in a critical path?
Edit: following are some code sample. They're OCaml and the data structures are different (some of them use libraries from Batteries), but the ideas are the same.
(* using a reference as accumulator *)
let most_significant_bit input_bits =
let result = ref None in
for i = Array.length input_bits - 1 downto 0 do
if input_bits.(i) then
if !result = None then
result := Some i
done;
!result
let most_significant_bit input_bits =
let result = ref None in
for i = 0 to Array.length input_bits - 1 do
if input_bits.(i) then
(* only the last one will be kept *)
result := Some i
done;
!result
(* simple recursive version *)
let most_significant_bit input_bits =
let rec loop = function
| -1 -> None
| i ->
if input_bits.(i) then Some i
else loop (i - 1)
in
loop (Array.length input_bits - 1)
(* higher-order traversal *)
open Batteries_uni
let most_significant_bit input_bits =
Array.fold_lefti
(fun result i ->
if input_bits.(i) && result = None then Some i else result)
None input_bits
(* traversal using an intermediate lazy data structure
(a --- b) is the decreasing enumeration of integers in [b; a] *)
open Batteries_uni
let most_significant_bit input_bits =
(Array.length input_bits - 1) --- 0
|> Enum.Exceptionless.find (fun i -> input_bits.(i))
(* using an exception to break out of the loop; if I understand
correctly, exceptions are rather discouraged in F# for efficiency
reasons. I proposed to use `yield` instead and then force the
generator, but this has no direct OCaml equivalent. *)
exception Result of int
let most_significant_bit input_bits =
try
for i = Array.length input_bits - 1 downto 0 do
if input_bits.(i) then raise (Result i)
done;
None
with Result i -> Some i
Why using a loop when you can use high-order functions?
I would write:
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
Seq.cast<bool> inputBits |> Seq.tryFindIndex id
Seq module contains many functions for manipulating collections. It is often a good alternative to using imperative loops.
but I still want to know what I was
doing wrong above.
The body of a for loop is an expression of type unit. The only thing you can do from there is doing side-effects (modifying a mutable value, printing...).
In F#, a if then else is similar to ? : from C languages. The then and the else parts must have the same type, otherwise it doesn't make sense in a language with static typing. When the else is missing, the compiler assumes it is else (). Thus, the then must have type unit. Putting a value in a for loop doesn't mean return, because everything is a value in F# (including a if then).
+1 for gasche
Here are some examples in F#. I added one (the second) to show how yield works with for within a sequence expression, as gasche mentioned.
(* using a mutable variable as accumulator as per gasche's example *)
let findMostSignificantBitPosition (inputBits: BitArray) =
let mutable ret = None // 0
for i = inputBits.Length - 1 downto 0 do
if inputBits.[i] then ret <- i
ret
(* transforming to a Seq of integers with a for, then taking the first element *)
let findMostSignificantBitPosition2 (inputBits: BitArray) =
seq {
for i = 0 to inputBits.Length - 1 do
if inputBits.[i] then yield i
} |> Seq.head
(* casting to a sequence of bools then taking the index of the first "true" *)
let findMostSignificantBitPosition3 (inputBits: BitArray) =
inputBits|> Seq.cast<bool> |> Seq.findIndex(fun f -> f)
Edit: versions returning an Option
let findMostSignificantBitPosition (inputBits: BitArray) =
let mutable ret = None
for i = inputBits.Length - 1 downto 0 do
if inputBits.[i] then ret <- Some i
ret
let findMostSignificantBitPosition2 (inputBits: BitArray) =
seq {
for i = 0 to inputBits.Length - 1 do
if inputBits.[i] then yield Some(i)
else yield None
} |> Seq.tryPick id
let findMostSignificantBitPosition3 (inputBits: BitArray) =
inputBits|> Seq.cast<bool> |> Seq.tryFindIndex(fun f -> f)
I would recommend using a higher-order function (as mentioned by Laurent) or writing a recursive function explicitly (which is a general approach to replace loops in F#).
If you want to see some fancy F# solution (which is probably better version of using some temporary lazy data structure), then you can take a look at my article which defines imperative computation builder for F#. This allows you to write something like:
let findMostSignificantBitPosition (inputBits:BitArray) = imperative {
for b in Seq.cast<bool> inputBits do
if b then return true
return false }
There is some overhead (as with using other temporary lazy data structures), but it looks just like C# :-).
EDIT I also posted the samples on F# Snippets: http://fssnip.net/40
I think the reason your having issues with how to write this code is that you're not handling the failure case of not finding a set bit. Others have posted many ways of finding the bit. Here are a few ways of handling the failure case.
failure case by Option
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
let rec loop i =
if i = -1 then
None
elif inputBits.[i] then
Some i
else
loop (i - 1)
loop (inputBits.Length - 1)
let test = new BitArray(1)
match findMostSignificantBitPosition test with
| Some i -> printf "Most Significant Bit: %i" i
| None -> printf "Most Significant Bit Not Found"
failure case by Exception
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
let rec loop i =
if i = -1 then
failwith "Most Significant Bit Not Found"
elif inputBits.[i] then
i
else
loop (i - 1)
loop (inputBits.Length - 1)
let test = new BitArray(1)
try
let i = findMostSignificantBitPosition test
printf "Most Significant Bit: %i" i
with
| Failure msg -> printf "%s" msg
failure case by -1
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
let rec loop i =
if i = -1 then
i
elif inputBits.[i] then
i
else
loop (i - 1)
loop (inputBits.Length - 1)
let test = new BitArray(1)
let i = findMostSignificantBitPosition test
if i <> -1 then
printf "Most Significant Bit: %i" i
else
printf "Most Significant Bit Not Found"
One of the options is to use seq and findIndex method as:
let findMostSignificantBitPosition (inputBits:System.Collections.BitArray) =
seq {
for i = inputBits.Length - 1 to 0 do
yield inputBits.[i]
} |> Seq.findIndex(fun e -> e)