I want to know is it even possible to create a watchdog on a program,
I am trying to do Discrete event simulation to simulate a functioning machine,
the problem is, once I inspect my machine at let's say time = 12 (inspection duration is 2 hours lets say) if the event failure is at 13-time units) there is no way that it can be because I am "busy inspecting"
so is there a sort of "watchdog" to constantly test if the value of a variable reached a certain limit to stop doing what the program is doing,
Here is my inspection program
def machine_inspection(tt, R, Dpmi, Dinv, FA, TRF0, Tswitch, Trfn):
End = 0
TPM = 0
logging.debug(' cycle time %f' % tt)
TRF0 = TRF0 - Dinv
Tswitch = Tswitch - Dinv
Trfn = Trfn - Dinv
if R == 0:
if falsealarm == 1:
FA += 1
else:
tt = tt + Dpmi
TPM = 1
End = 1
return (tt, End, R, TPM, FA, TRF0, Trfn, Tswitch)
Thank you very much!
basically you can't be inspecting during x time if tt + x will be superior to the time to failure TRF0 or Trfn
Related
New to algorithms
Trying a Binary Search problem, below is my code -
def search(nums, target):
low = 0
high = len(nums) - 1
#a = sorted(nums) --> to sort the list if needed [ change nums to a ]
while low <= high:
middle = (low + high) // 2
if target == nums[middle]:
return middle
elif target > nums[middle]:
low = middle + 1
else:
high = middle - 1
else:
return -1
Code is running fine with a runtime of 402 ms. Then I checked the code of other people and one of them had
middle = low + (high - low) // 2
and their runtime is 110 ms. Can someone please explain why such a difference is there between the runtime?
I'm fairly new to threading, and I am trying to adapt some code to make it threadsafe.
My problem is that multiple threads access multiple methods of a single instance at the same time. Because the methods both use and change the instances state, bad things obviously happen...
I want each instance to be accessed by only 1 thread at a time (i.e. only one method of that instance running at any time and any other threads should wait).
As a note, the threads are spawned from a Dash app, so I include that keyword in case others end up here, but I don't think it makes a difference to the problem overall.
I'll start with a very simple case and then add in the complexity that I want to achieve (although it may not affect the solution).
Simple Case
Let's say I have a class like this:
class BaseClass:
pass
class Simple(BaseClass):
def __init__(self, a=1):
self.a = a
self.b = None
def print(self):
print(f'a = {self.a}, b = {self.b}')
time.sleep(1)
self.b = 'b_set'
I want to be able to run the following tests:
if __name__ == '__main__':
test1 = Simple(a=1)
test2 = Simple(a=2)
t1 = threading.Thread(target=test1.print)
t2 = threading.Thread(target=test2.print)
t3 = threading.Thread(target=test1.print) # Another call to test1.print
threads = (t1, t2, t3)
print('Starting all threads')
start_time = time.time()
for t in threads:
t.start()
for t in threads:
t.join()
print(f'Aiming for 2s of execution, took {time.time()-start_time:.1f}s')
I am aiming to see this output:
Starting all threads
a = 1, b = None
a = 2, b = None
a = 1, b = b_set
Aiming for 2s of execution, took 2.0s
but what I actually see is:
Starting all threads
a = 1, b = None
a = 2, b = None
a = 1, b = None
Aiming for 2s of execution, took 1.0s
Where crucially the execution time SHOULD be 2.0s (where it is currently 1.0s) because I want t1 and t2 to run concurrently and then I want t3 to run (i.e. t3 should not be running at the same time as t1).
I want to modify BaseClass so that this works.
I found this (Synchronizing All Methods in an Object) which I believe is a solution, however, it is written for Python 2, and I believe there is a much cleaner solution possible in Python 3 based on this (How to synchronize all methods in class python3?).
The second solution is very close, it does make the Simple class threadsafe, but it also prevents t1 and t2 from running at the same time because it applies to the whole subclass, not the instances of the subclass. I don't understand the ins and outs of __init_subclass__ well enough to know how to modify this behaviour in a nice way.
Any help would be greatly appreciated!
More complex examples to further illustrate intention and more difficult cases
class BaseClass(abc.ABC):
def __init__(self, a=1):
self.a = a
def print(self):
print(f'a = {self.a}')
time.sleep(1)
def print_get(self):
print(f'get_a = {self.get_a()}')
time.sleep(1)
def get_a(self):
"""An example of some methods having to call other methods of self"""
return self.a
#abc.abstractmethod
def reentrant_print(self, i=0):
"""Something which has to reenter itself (or other methods of self)"""
pass
class SubClass(BaseClass):
def reentrant_print(self, i=0):
"""Should print three times in a row"""
print(f'a = {self.a}: i = {i}\n')
time.sleep(0.5)
if i < 3:
self.reentrant_print(i+1)
if __name__ == '__main__':
test1 = SubClass(a=1)
test2 = SubClass(a=2)
methods = ('print', 'print_get', 'reentrant_print')
for method in methods:
print(f'\n\nStarting tests for method = {method}')
t1 = threading.Thread(target=getattr(test1, method))
t2 = threading.Thread(target=getattr(test2, method))
t3 = threading.Thread(target=getattr(test1, method)) # Another call to test1
t4 = threading.Thread(target=test1.print) # Another call to test1 on a different method
threads = (t1, t2, t3, t4)
print('Starting all threads')
start_time = time.time()
for t in threads:
t.start()
for t in threads:
t.join()
print(f'All threads finished in {time.time()-start_time:.1f}s')
Aiming for Output to be something like:
Starting tests for method = print
Starting all threads
a = 1
a = 2
a = 1
a = 1
All threads finished in 3.0s <<<<< Note: Should be 3.0s because it should run t1 and t2, then t3, then t4
Starting tests for method = print_get
Starting all threads
get_a = 1
get_a = 2
get_a = 1
a = 1
All threads finished in 3.0s <<<<< Note: Should be 3.0s because it should run t1 and t2, then t3, then t4 (or could allow t4 to run at same time as t1 and t2)
Starting tests for method = reentrant_print
Starting all threads
a = 1: i = 0
a = 2: i = 0
a = 1: i = 1
a = 2: i = 1
a = 1: i = 2
a = 2: i = 2
a = 1: i = 3
a = 2: i = 3
a = 1: i = 0 <<< Note: From ~here it should be only t3 running
a = 1: i = 1
a = 1: i = 2
a = 1: i = 3
All threads finished in 4.0s <<<<< Note: Should be 4.0s because it should run t1 and t2, then t3, then t4
Even just shedding some light on the Simple Case would be very helpful, although I include the more complex cases in case it is easy to extend behaviour if you know what you're doing!
I wrote a program a crystal program to calculate prime numbers upto a range with Sieve.
Code
#!/usr/bin/env crystal
def sieve(max)
t = Thread.new do
dot, ary, colours = ".", ["\xE2\xA0\x81", "\xE2\xA0\x88", "\xE2\xA0\xA0", "\xE2\xA0\x84"] * 2, [154, 184, 208, 203, 198, 164, 129, 92]
print "\e[?25l"
loop do
ary.size.times do |x|
print("\e[2K#{ary[x]} \e[38;5;#{colours[x]}mPlease Wait#{dot * x}\e[0m\r")
sleep(0.1)
end
end
end
s = [nil, nil] + (2..max).to_a
s.each do |x|
next unless x
break if (sq = x ** 2) > max
(sq..max).step(x) { |y| s[y] = nil }
end
puts "\e[?25h"
s.tap { |x| x.compact! }
end
p sieve(2_000_000).size
The way I want to display it is
Issue
The problem is the thread isn't killed when puts is writing the sieve. the method sieve(n) just returns an array. The array size then is calculated, and printed. You can see that the animation freezes for a time, and then continues until it's printed and exited. If I use spawn do...end the print in spawn pauses until the sieve is calculated.
Not killing threads causes issues like this
In ruby I used to do
t = Thread.new { loop while ... }
<some other time consuming stuff here>
t.kill
return calculated_stuffs
Crystal Details
Crystal 0.31.1 (2019-10-21)
LLVM: 9.0.0
Default target: x86_64-pc-linux-gnu
How to kill a thread in crystal?
Thread is part of Crystal's internal API, and is not meant to be used directly.
The good news is Crystal natively supports a concurrency model called CSP, where Fibers (light-weight threads) send each others messages over thread-safe Channels in order to coordinate. So, rather than communicating by sharing state, Fibers share state by communicating - as they say in golang.
For your use case, you could run 3 Fibers:
A sieve, generating numbers and sending updates through a channel
A monitor, receiving on the sieve's channel, updating the UI and sending a completion message once the sieve is done
The main Fiber, waiting for the monitor to notify completion and able to decide what to do with the sieve's result
Here is what your code could look like
record Result, primes : Array(Int32)
record Tick
alias SieveUpdate = Result | Tick
def monitor(updates : Channel(SieveUpdate)) : Channel(Result)
Channel(Result).new.tap { |done|
spawn do
dot, ary, colours = ".", ["\xE2\xA0\x81", "\xE2\xA0\x88", "\xE2\xA0\xA0", "\xE2\xA0\x84"] * 2, [154, 184, 208, 203, 198, 164, 129, 92]
ary_idx = 0
update_n = 0
print "\e[?25l"
loop do
case value = updates.receive
when Tick
next unless (update_n+=1) % 50 == 0 # lower refresh rate
print("\e[2K#{ary[ary_idx]} \e[38;5;#{colours[ary_idx]}mPlease Wait#{dot * ary_idx}\e[0m\r")
ary_idx = (ary_idx + 1) % ary.size
when Result
puts "\e[?25h"
done.send value
break
end
end
end
}
end
def sieve(max) : Channel(SieveUpdate)
Channel(SieveUpdate).new.tap { |updates|
spawn do
s = [nil, nil] + (2..max).to_a
s.each do |x|
updates.send(Tick.new)
next unless x
break if (sq = x ** 2) > max
(sq..max).step(x) { |y| s[y] = nil }
end
updates.send Result.new(s.compact.as(Array(Int32)))
end
}
end
updates = sieve(2_000_000)
done = monitor(updates)
print done.receive.primes.size
So I have this rain module for a game that I am developing, which is causing a massive system memory leak, which leads to lag and ultimately crash of the application.
The function "t.start" is called with a timer every 50 ms.
Though I I've tried I can't really find the cause for this! Maybe I am overlooking something but I can't help it. As you see I niled out the graphics related locals...Does anyone notice something?
As a secondary issue : Does anyone have tips on preloading next scene for a smooth scene change? Because the loading itself is causing a short freeze when I put it in "scene:show()"...
Thanks for your help!
Greetings, Nils
local t = {}
local composer = require("composer")
t.drops = {}
function t.fall(drops, group)
for i = 1, #drops, 1 do
local thisDrop = drops[i]
function thisDrop:enterFrame()
if aboutToBeDestroyed == true then
Runtime:removeEventListener("enterFrame", self)
return true
end
local randomY = math.random(32, 64)
if self.x ~= nil then
self:translate(0, randomY)
if self.y > 2000 then
self:removeSelf()
Runtime:removeEventListener("enterFrame", self)
self = nil
end
end
end
Runtime:addEventListener("enterFrame", drops[i])
thisDrop = nil
end
end
t.clean = function()
for i = 1, #t.drops, 1 do
if t.drops[i] ~= nil then
table.remove(t.drops, i)
t.drops[i] = nil
end
end
end
function t.start(group)
local drops = {}
local theGroup = group
for i = 1, 20, 1 do
local randomWidth = math.random(5, 30)
local dropV = display.newRect(group, 1, 1, randomWidth, 30)
local drop1 = display.newSnapshot(dropV.contentWidth , dropV.contentHeight * 3)
drop1.canvas:insert(dropV)
drop1.fill.effect = "filter.blurVertical"
drop1.fill.effect.blurSize = 30
drop1.fill.effect.sigma = 140
drop1:invalidate("canvas")
drop1:scale(0.75, 90)
drop1:invalidate("canvas")
drop1:scale(1, 1 / 60)
drop1:invalidate("canvas")
local drop = display.newSnapshot(drop1.contentWidth * 1.5, drop1.contentHeight)
drop.canvas:insert(drop1)
drop.fill.effect = "filter.blurHorizontal"
drop.fill.effect.blurSize = 10
drop:invalidate("canvas")
drop.alpha = 0.375
local randomY = math.random(-500, 500)
drop.y = randomY
drop.anchorY = 0
drop.x = (i - 1) * 54
drops[i] = drop
table.insert(t.drops, drop)
local dropV, drop1, drop = nil
end
composer.setVariable("drops", t.drops)
t.fall(drops, group)
drops = nil
t.clean()
end
return t
EDIT : I found out that it definitely has something to do with the nested snapshots, which are created for the purpose of applying filter effects. I removed one snapshot, so that I only have a vector object inside a snapshot and voila : memory increases way slower. The question is : why?
Generally, you don't need enterFrame event at all - you can simply do transition from start point (math.random(-500, 500)) to end point (2000 in your code). Just randomise speed and use onComplete handler to remove object
local targetY = 2000
local speedPerMs = math.random(32, 64) * 60 / 1000
local timeToTravel = (targetY - randomY) / speedPerMs
transition.to( drop, {
time = timeToTravel,
x = xx,
y = targetY,
onComplete = function()
drop:removeSelf()
end
} )
Edit 1: I found that with your code removing drop is not enough. This works for me:
drop:removeSelf()
dropV:removeSelf()
drop1:removeSelf()
Some ideas about memory consumption:
1) Probably you can use 1 enterFrame handler for array of drops - this will reduce memory consumption. Also don't add methods to local objects like 'function thisDrop:enterFrame()' - this is not optimal here, because you creating 20 new functions every 50 ms
2) Your code creates 400 'drop' objects every second and they usually live no more than ~78 frames (means 1.3 sec in 60fps environment). Better to use pool of objects and reuse existing objects
3) enterFrame function depends on current fps of device, so your rain will be slower with low fps. Low fps -> objects falls slower -> more objects on scene -> fps go down. I suggest you to calculate deltaTime between 2 enterFrame calls and ajust falling speed according to deltaTime
Edit 2 Seems like :removeSelf() for snapshot didn't remove child object. I modified your code and memory consumption drops a lot
if self.y > 2000 then
local drop1 = self.group[1]
local dropV = drop1.group[1]
dropV:removeSelf()
drop1:removeSelf()
self:removeSelf()
Runtime:removeEventListener("enterFrame", self)
self = nil
end
I'm try to run an ocean temperature model for 25 years using the explicit method (parabolic differential equation).
If I run for a year a = 3600 or five years a = 18000 it works fine.
However, when I run it for 25 years a = 90000 it crashes.
a is the amount of time steps used. And a year is considered to be 360 days. The time step is 4320 seconds, delta_t = 4320..
Here is my code:
program task
!declare the variables
implicit none
! initial conditions
real,parameter :: initial_temp = 4.
! vertical resolution (delta_z) [m], vertical diffusion coefficient (av) [m^2/s], time step delta_t [s]
real,parameter :: delta_z = 2., av = 2.0E-04, delta_t = 4320.
! gamma
real,parameter :: y = (av * delta_t) / (delta_z**2)
! horizontal resolution (time) total points
integer,parameter :: a = 18000
!declaring vertical resolution
integer,parameter :: k = 101
! declaring pi
real, parameter :: pi = 4.0*atan(1.0)
! t = time [s], temp_a = temperature at upper boundary [°C]
real,dimension(0:a) :: t
real,dimension(0:a) :: temp_a
real,dimension(0:a,0:k) :: temp
integer :: i
integer :: n
integer :: j
t(0) = 0
do i = 1,a
t(i) = t(i-1) + delta_t
end do
! temperature of upper boundary
temp_a = 12. + 6. * sin((2. * t * pi) / 31104000.)
temp(:,0) = temp_a(:)
temp(0,1:k) = 4.
! Vertical resolution
do j = 1,a
do n = 1,k
temp(j,n) = temp(j-1,n) + (y * (temp(j-1,n+1) - (2. * temp(j-1,n)) + temp(j-1,n-1)))
end do
temp(:,101) = temp(:,100)
end do
print *, temp(:,:)
end program task
The variable a is on line 11 (integer,parameter :: a = 18000)
As said, a = 18000 works, a = 90000 doesn't.
At 90000 get I get:
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
RUN FAILED (exit value 1, total time: 15s)
I'm using a fortran on windows 8.1, NetBeans and Cygwin (which has gfortran built in).
I'm not sure if this problem is caused through bad compiler or anything else.
Does anybody have any ideas to this? It would help me a lot!
Regards
Take a look at the following lines from your code:
integer,parameter :: k = 101
real,dimension(0:a,0:k) :: temp
integer :: n
do n = 1,k
temp(j,n) = temp(j-1,n) + (y * (temp(j-1,n+1) - (2. * temp(j-1,n)) + temp(j-1,n-1)))
end do
Your array temp has bounds of 0:101, you loop n from 1 to 101 where in iteration n=101 you access temp(j-1,102), which is out of bounds.
This means you are writing to whatever memory lies beyond temp and while this makes your program always incorrect, it is only causing a crash sometimes which depends on various other things. Increasing a triggers this because column major ordering of your array means k changes contiguously and is strided by a, and as a increases your out of bounds access of the second dimension is further in memory beyond temp changing what is getting overwritten by your invalid access.
After your loop you set temp(:,101) = temp(:,100) meaning there is no need to calculate temp(:,101) in the above loop, so you can change its loop bounds from
do n = 1,k
to
do n = 1, k-1
which will fix the out of bounds access on temp.