jjzjj

去超时不开火

coder 2024-07-10 原文

为了好玩,我在 Go 中实现了一些排序算法,现在我想测试它们对随机整数的性能。所以我写了下面的程序。我遵循了类似的格式:https://gobyexample.com/timeouts

但是,似乎超时未正确触发。下面是我的代码:

package main

import (
    "allanpinkerton.com/algorithms/sorting"
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "time"
)

// Prints out the time elapsed since start
func timeExecution(startTime time.Time, functionName string, inputSize int) string {
    executionTime := time.Since(startTime)
    return fmt.Sprintf("%-20s took %10.4fms to sort %d elements\n", functionName, float64(executionTime.Nanoseconds())/1000000, inputSize)
}

// Generates file with n random ints named integerArray + n
func generateRandomIntegers(n int, filename string) {
    arr := make([]int, n)
    for i := 0; i < n; i++ {
        arr[i] = rand.Int()
    }
    f, _ := os.Create(filename)
    defer f.Close()
    for _, num := range arr {
        f.WriteString(strconv.Itoa(num) + " ")
    }
    f.WriteString("\n")
    f.Sync()
    fmt.Printf("Generated " + filename + " with " + strconv.Itoa(n) + " elements.\n")
}


func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {

    sortingFunctions := map[string]interface{}{
        "InsertionSort":        sorting.InsertionSort,
        "QuickSortLastElement": sorting.QuickSortLastElement,
        "QuickSortRandom":      sorting.QuickSortRandom,
    }
    if len(os.Args) != 2 {
        fmt.Printf("No size specified.\n")
        return
    }
    size := os.Args[1]
    sizeInt, err := strconv.Atoi(size)
    checkError(err)

    arr := make([]int, sizeInt)
    for i := 0; i < sizeInt; i++ {
        arr[i] = rand.Int()
    }
    fmt.Println("Generated " + size + " integers.")

    mainChannel := make(chan string)
    for k, v := range sortingFunctions {
        newArr := make([]int, len(arr))
        copy(newArr, arr)
        go func(name string, v interface{}) {
            start := time.Now()
            v.(func([]int))(newArr)
            result := timeExecution(start, name, len(newArr))
            mainChannel <- result
        }(k, v)
    }

    for _ = range sortingFunctions {
        select {
        case result := <-mainChannel:
            fmt.Printf(result)
        case <-time.After(time.Second):
            fmt.Println("Timeout")
        }
    }

    return
}

top 只是一堆助手,但是 main 函数发生了一些有趣的事情。我运行 go install 并针对 150,000 个元素运行它,得到以下响应:

Generated 150000 integers.
QuickSortLastElement took    15.0037ms to sort 150000 elements
InsertionSort        took  7599.5884ms to sort 150000 elements
QuickSortRandom      took    15.1697ms to sort 150000 elements

很明显,插入排序用了 7 秒,但超时应该在 1 秒后触发。超时不触发有什么原因吗?

因此,我尝试通过将 sortingFuncs 映射更改为:

sortingFunctions := map[string]func([]int){
    "InsertionSort":        sort.Ints,
    "QuickSortLastElement": sort.Ints,
    "QuickSortRandom":      sort.Ints,
}

然后问题就解决了。所以是我的自定义排序函数阻止了超时被触发。我必须向这些函数添加一些东西才能使它们并行运行吗?

这是 playground 中所有代码的合并版本。 https://play.golang.org/p/SBgDTGyUyp

最佳答案

由于您在最终循环中使用了 time.After(time.Second),因此每次结果到达时您都将重置超时。相反,尝试

timeoutChannel := time.After(time.Second)
for _ = range sortingFunctions {
    select {
    case result := <-mainChannel:
        fmt.Printf(result)
    case <-timeoutChannel:
        fmt.Println("Timeout")
    }
}

上面的代码现在可以正确捕获超时。它仍然没有按预期工作,因为循环的内容总是执行三次(因为 sortingFunctions 有三个元素),并且任何超时都计入这三次迭代。使用你在 go playground 中的代码,我现在得到以下输出:

Generated 90000 integers.
QuickSortRandom      took     9.4268ms to sort 90000 elements
Timeout
QuickSortLastElement took     8.6096ms to sort 90000 elements

关于去超时不开火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31643203/

有关去超时不开火的更多相关文章

  1. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  2. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  3. Ruby 在 n *milli* 秒后超时一段代码 - 2

    在Ruby中,我需要在n毫秒秒后暂停一段代码的执行。我知道RubyTimeout库支持秒的超时:http://ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html这可能吗? 最佳答案 只需为超时使用十进制值。n毫秒的示例:Timeout::timeout(n/1000.0){sleep(100)} 关于Ruby在n*milli*秒后超时一段代码,我们在StackOverflow上找到一个类似的问题: https:

  4. ruby-on-rails - unicorn 超时处理 - 2

    我想知道从我的应用程序跟踪unicorn超时的最佳方法是什么。该应用程序的某些部分运行缓慢,目前它们已安静地超时。我可以增加超时时间,但这将问题推到了地毯下。理想情况下,我希望收到减速板通知或类似的效果。我不是在寻找性能指南,我只是在寻找一种高效可靠地了解超时的方法。其他人如何使用unicorn处理Rails应用程序的超时?扫描nginx错误日志?在unicorn配置中插入处理程序?nginx配置中的处理程序?[Ubuntu12.04+nginx+unicorn+rails3.2+ruby1.9.3] 最佳答案 我倾向于在NewRe

  5. ruby - 在 AWS Linux 上增加 RestClient/Net::HTTP 中的 connect(2) 超时 - 2

    我正在使用rest-client发布到一个非常慢的网络服务。我将timeout设置为600秒,并且我已经确认它正在传递给Net::HTTP的@read_timeout和@open_timeout.但是,大约两分钟后,我收到一个低级超时错误,Errno::ETIMEDOUT:Connectiontimedout-connect(2):回溯的相关部分是Operationtimedout-connect(2)for[myhost]port[myport]/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:879:in

  6. ruby-on-rails - 如何在 sidekiq 中设置作业超时 - 2

    我遇到了sidekiq的问题:我想为作业设置超时,这意味着当作业的处理时间大于超时时,该作业将停止。我已经搜索了如何在文件sidekiq.yml中设置全局超时配置。但是我想为不同的单独作业设置单独的超时,这意味着定义工作人员的类之一将具有特定的超时配置。你能帮帮我吗?非常感谢。 最佳答案 没有批准的方法可以做到这一点。您无法在线程执行时安全地停止它。您需要更改工作以定期检查它是否应该停止。您可以为您正在进行的任何第3方调用设置网络超时,以便它们超时。 关于ruby-on-rails-如何

  7. ruby - 超时::在 ruby​​ 中使用 selenium-webdriver 时出错 - 2

    自从我开始开发测试以来,我一直收到超时错误。起初我认为这与我的xpaths的效率有关,但在多次看到测试快速通过后,我认为这与选择器无关。该错误是随机发生的,并且通常在一个特征中多次发生。我需要修复或至少了解这个问题是什么。步骤定义示例:When/^Inavigateto"(.*)"$/do|webpage|navigate_to(webpage)end这是我得到的错误:Timeout::Error(Timeout::Error)/usr/lib/ruby/1.9.1/net/protocol.rb:146:in`rescueinrbuf_fill'/usr/lib/ruby/1.9.1

  8. ruby-on-rails - 如何在可配置的超时时间内响应 Rails 请求 - 2

    我想在不使用超时模块的情况下在Controller的操作中实现以下行为:classAdminController我想避免使用超时,因为它会在我的应用程序中导致许多错误,包括数据库连接泄漏。报告的其他一些问题:http://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/ 最佳答案 不要为此使用ruby。问题是超时模块将在执行代码的任何地方中止代码,这将导致打开和悬空的套接字、连接和文件或更糟。(我想,如果你启动外部脚本或为每项工作支付费用,这并不是真正的问

  9. ruby - 使用 ruby​​ mechanize 捕获超时错误 - 2

    我有一个Mechanize功能可以让我退出网站,但在极少数情况下它会让我超时。该功能涉及转到特定页面,然后单击注销按钮。有时,当进入注销页面或单击注销按钮时,mechanize会遇到超时,代码会崩溃。所以我做了一个小的救援,它似乎在第一段代码下面看到的那样工作。deflogmeout(agent)page=agent.get('http://www.example.com/')agent.click(page.link_with(:text=>/LogOut/i))end通过救援注销:deflogmeout(agent)beginpage=agent.get('http://www.e

  10. Ruby Net::FTP 超时线程 - 2

    我试图通过使用线程FTP连接来加速多个FTP下载。我的问题是我总是有线程挂起。我正在寻找一种干净的方法来告诉FTP它需要重试ftp事务,或者至少知道FTP连接何时挂起。在下面的代码中,我对5/6个单独的FTP连接进行线程处理,其中每个线程都有一个预期下载的文件列表。当脚本完成时,一些线程挂起并且无法加入。我使用变量@last_updated来表示上次成功下载的时间。如果当前时间+20秒超过了@last_updated,就杀掉剩下的线程。有没有更好的办法?threads=[]max_thread_pool=5running_threads=0Thread.abort_on_excepti

随机推荐