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

我正在Go中为SQRL客户端实施EnScrypt.该函数需要运行,直到它使用最少的CPU时间.我的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,32)
        acc = xor_bytes(acc,data)
        i += 1
    return i,time.process_time() - start,acc

除了process_time函数之外,将其转换为Go非常简单.
我无法使用time.Time / Timer,因为它们会测量挂钟时间(受系统上可能正在运行的其他所有内容的影响).我需要实际使用的CPU时间,理想情况是函数,或者至少需要运行的线程或进程.

Go等效于process_time是什么?

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

最佳答案
您可以使用runtime.LockOSThread()将调用goroutine连接到其当前的OS线程.这将确保不会为此线程安排其他goroutine,因此您的goroutine将运行而不会被中断或暂停.当线程被锁定时,没有其他goroutine会干扰.

在此之后,您只需要一个循环,直到给定的秒数过去.您必须调用runtime.UnlockOSThread()以“释放”该线程并使其可供其他goroutine执行,最好以延迟语句完成.

看这个例子:

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

为了使它等待2秒,它可能看起来像这样:

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

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

这打印例如:

Verify: 2.0004556s

当然,您也可以指定不到一秒钟,例如等待100毫秒:

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

输出:

Verify: 100.1278ms

您可以使用此功能的不同版本,如果这更适合您,需要花费时间“等待”作为值time.Duration

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

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

使用这个:

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

输出:

Verify: 200.1546ms

注意:请注意,上述函数中的循环将无情地使用CPU,因为它们没有睡眠或阻塞IO,它们只查询当前系统时间并将其与截止时间进行比较.

如果攻击者通过多次并发尝试增加系统负载怎么办?

Go运行时限制了可以同时执行goroutine的系统线程.这是由runtime.GOMAXPROCS()控制的,所以这已经是一个限制.它默认为可用CPU核心数,您可以随时更改它.这也是一个瓶颈,因为通过使用runtime.LockOSThread(),如果锁定线程的数量在任何给定时间等于GOMAXPROCS,那将阻止其他goroutine的执行,直到线程被解锁.

查看相关问题:

Number of threads used by Go runtime

Why does it not create many threads when many goroutines are blocked in writing file in golang?

相关文章

Python中的函数(二) 在上一篇文章中提到了Python中函数的定...
Python中的字符串 可能大多数人在学习C语言的时候,最先接触...
Python 面向对象编程(一) 虽然Python是解释性语言,但是它...
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定...
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非...
在windows下如何快速搭建web.py开发框架 用Python进行web开发...