简体   繁体   English

如何确保函数在Go中占用一定的时间?

[英]How can I ensure that a function takes a certain amount of time in Go?

I am implementing EnScrypt for an SQRL client in Go. 我正在Go中为SQRL客户端实施EnScrypt。 The function needs to run until it has used a minimum amount of CPU time. 该函数需要运行,直到它使用最少的CPU时间。 My Python code looks like this: 我的Python代码如下所示:

def enscrypt_time(salt, password, seconds, n=9, r=256):
    N = 1 << n
    start = time.process_time()
    end = start + seconds
    data = acc = scrypt.hash(password, salt, N, r, 1, 32)
    i = 1
    while time.process_time() < end:
        data = scrypt.hash(password, data, N, r, 1, 32)
        acc = xor_bytes(acc, data)
        i += 1
    return i, time.process_time() - start, acc

Converting this to Go is pretty simple except for the process_time function. 除了process_time函数之外,将其转换为Go非常简单。 I can't use time.Time / Timer because those measure wall-clock time (which is affected by everything else that may be running on the system). 我无法使用time.Time / Timer因为它们会测量挂钟时间(受系统上可能正在运行的其他所有内容的影响)。 I need the CPU time actually used, ideally by the function, or at least by the thread or process it is running in. 我需要实际使用的CPU时间,理想情况是函数,或者至少需要运行的线程或进程。

What is the Go equivalent of process_time ? Go等效于process_time什么?

https://docs.python.org/3/library/time.html#time.process_time https://docs.python.org/3/library/time.html#time.process_time

You may use runtime.LockOSThread() to wire the calling goroutine to its current OS thread. 您可以使用runtime.LockOSThread()将调用goroutine连接到其当前的OS线程。 This will ensure that no other goroutines will be scheduled to this thread, so your goroutine will run and not get interrupted or put on hold. 这将确保不会将其他goroutine安排到此线程,因此您的goroutine将运行而不会被中断或暂停。 No other goroutines will interfere when thread is locked. 当线程被锁定时,没有其他goroutine会干扰。

After this, you just need a loop until the given seconds have passed. 在此之后,您只需要一个循环,直到给定的秒数过去。 You must call runtime.UnlockOSThread() to "release" the thread and make it available for other goroutines for execution, best done as a defer statement. 您必须调用runtime.UnlockOSThread()来“释放”该线程并使其可供其他goroutine执行,最好以defer语句完成。

See this example: 看这个例子:

func runUntil(end time.Time) {
    runtime.LockOSThread()
    defer runtime.UnlockOSThread()
    for time.Now().Before(end) {
    }
}

To make it wait for 2 seconds, it could look like this: 为了使它等待2秒,它可能看起来像这样:

start := time.Now()
end := start.Add(time.Second * 2)
runUntil(end)

fmt.Println("Verify:", time.Now().Sub(start))

This prints for example: 这打印例如:

Verify: 2.0004556s

Of course you can specify less than a second too, eg to wait for 100 ms: 当然你也可以指定不到一秒钟,例如等待100毫秒:

start := time.Now()
runUntil(start.Add(time.Millisecond * 100))
fmt.Println("Verify:", time.Now().Sub(start))

Output: 输出:

Verify: 100.1278ms

You may use a different version of this function if that suits you better, one that takes the amount of time to "wait" as a value of time.Duration : 您可以使用此功能的不同版本,如果这更适合您,需要花费时间“等待”作为时间值time.Duration

func wait(d time.Duration) {
    runtime.LockOSThread()
    defer runtime.UnlockOSThread()

    for end := time.Now().Add(d); time.Now().Before(end); {
    }
}

Using this: 使用这个:

start = time.Now()
wait(time.Millisecond * 200)
fmt.Println("Verify:", time.Now().Sub(start))

Output: 输出:

Verify: 200.1546ms

Note: Note that the loops in the above functions will use CPU relentlessly as there is no sleep or blocking IO in them, they will just query the current system time and compare it to the deadline. 注意:请注意,上述函数中的循环将无情地使用CPU,因为它们没有睡眠或阻塞IO,它们只查询当前系统时间并将其与截止时间进行比较。

What if the attacker increases system load by multiple concurrent attempts? 如果攻击者通过多次并发尝试增加系统负载怎么办?

The Go runtime limits the system threads that can simultaneously execute goroutines. Go运行时限制了可以同时执行goroutine的系统线程。 This is controlled by runtime.GOMAXPROCS() , so this is already a limitation. 这是由runtime.GOMAXPROCS()控制的,所以这已经是一个限制。 It defaults to the number of available CPU cores, and you can change it anytime. 它默认为可用CPU核心数,您可以随时更改它。 This also poses a bottleneck though, as by using runtime.LockOSThread() , if the number of locked threads equals to GOMAXPROCS at any given time, that would block execution of other goroutines until a thread is unlocked. 这也是一个瓶颈,因为通过使用runtime.LockOSThread() ,如果锁定线程的数量在任何给定时间等于GOMAXPROCS ,那将阻止其他goroutine的执行,直到线程被解锁。

See related questions: 查看相关问题:

Number of threads used by Go runtime Go运行时使用的线程数

Why does it not create many threads when many goroutines are blocked in writing file in golang? 当在golang中写入文件时阻塞了许多goroutine时,为什么不创建多个线程?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在一定时间后停止“input()”function? - How can I stop the 'input()' function after a certain amount of time? 如何确保 Python while 循环需要特定的时间来运行? - How do I ensure that a Python while-loop takes a particular amount of time to run? 我无法在一定时间内循环运行 function - I can't run a function in a loop for certain amount of time 如何在一定时间内运行代码? - How can I run code for a certain amount of time? 如何让文本在屏幕上显示一段时间? - How can I get a text to appear for a certain amount of time on the screen? 如何调用方法并确保其执行不超过特定时间? - How can I call a method and ensure that it its execution doesn't exceed a certain time? 我如何使用 Pygame 中的时钟/刻度 function 在一定时间后生成另一个 object? - How do I use the clock/ticks function in Pygame to spawn another object after a certain amount of time? 如何每隔一定时间通过套接字无限发送数据? - How can I get data to be sent over sockets infinitely every certain amount of time? 如何在熊猫的某个时间段内选择最少的 nan 值? - How can I select with least amount of nan values for a certain time period in panda? 如何在python中使Tkinter在一定时间内完成每个代码? - How can I make Tkinter in python to do every code in certain amount of time?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM