Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Penjelasan terperinci tentang masalah ralat tambah apabila Go mempunyai konkurensi yang tinggi!

Penjelasan terperinci tentang masalah ralat tambah apabila Go mempunyai konkurensi yang tinggi!

藏色散人
藏色散人ke hadapan
2022-10-31 16:14:413016semak imbas

Artikel ini adalah daripada lajur tutorial golang untuk memperkenalkan kepada anda ralat sekali-sekala dalam kaedah tambah apabila pergi sangat bersesuaian Perkara berikut akan menerangkan kaedah ini secara terperinci kawan yang memerlukan!

Latar Belakang

Apabila melaksanakan keperluan transkod imej, adalah perlu untuk menyokong sehingga 500 imej selepas memuat turun dan menukar format

Jika anda memuat turunnya satu demi satu Selepas transcoding, ia mengambil masa terlalu lama Anda perlu menggunakan goroutine untuk mencapai muat turun serentak 500 imej dan transcoding serentak

Walau bagaimanapun, semasa ujian kendiri, didapati hanya 499 imej atau lebih; telah ditukar selepas memuat turun. Terdapat beberapa kes (dengan syarat semua muat turun dan transcoding berjaya);

Penyelesaian masalah

Oleh kerana penyegerakan digunakan semasa concurrency untuk menunggu semua coroutine tamat, pada mulanya saya fikir terdapat masalah dengan penyegerakan menunggu tak segerak

Log cetak Didapati bahawa 500 muat turun telah dilaksanakan seperti biasa Selepas muat turun selesai, operasi transcoding diteruskan untuk menghapuskan masalah dengan menunggu tak segerak penyegerakan

Kodnya adalah seperti berikut:

Log adalah seperti berikut:
import (
   "github.com/satori/go.uuid"
   "sync"
)
func downloadFiles(nWait *sync.WaitGroup, urls []interface{}, successFiles *[]string, failedFiles *[]string) {
   // 遍历 urls 进行下载
   for _, value := range urls {
   go func(value interface{}) {
   defer nWait.Done()                                                     // 执行结束,协程减 1
   fullname := config.TranscodeDownloadPath + "/" + uuid.NewV4().String() // 需要确保文件名的唯一性 (防止不同用户同一时间操作了同一文件,导致转码失败)
   err := utils.DownloadCeph(value.(string), fullname)                    // 下载文件
   // 下载文件状态记录
   if err != nil {
   *failedFiles = append(*failedFiles, fullname)
   } else {
   *successFiles = append(*successFiles, fullname)
   }
   }(value)
   }
}
// 前端传入的图片 url
strUrlList := req["strUrlList"]
// 初始化变量
nWait := sync.WaitGroup{}          // 多协程异步等待
var successFiles []string  // 下载成功文件
var failedFiles []string           // 下载失败文件
// 遍历 strUrlList 进行下载
log.Error("开始下载!长度:", len(strUrlList))
nWait.Add(len(strUrlList)) // 等待协程数
downloadFiles(&nWait, strUrlList, &successFiles, &failedFiles)
nWait.Wait() // 阻塞,等待完成
log.Error("下载结束!长度:", len(successFiles))
//...
log.Error("下载转码!")
//...

Cetak log yang lebih terperinci untuk menyelesaikan masalah logik dalam gelung julat untuk
2022-10-29 21:28:51.996 ERROR   services/tools.go:149   开始下载!长度:500
2022-10-29 21:28:52.486 ERROR   services/tools.go:153   下载结束!长度:499
2022-10-29 21:28:52.486 ERROR   services/tools.go:155   开始转码!

Tambah log pada penghujung gelung tunggal:

Menemui log Khas:
log.Error("下载协程结束: ", len(*successFiles))

Panjang kedua-dua masa ialah 65, dan panjang hirisan tidak berubah Jika kaedah tambah hirisan dilaksanakan dua kali pada masa yang sama masa, kegagalan akan berlaku sekali-sekala, dan punca masalah ditemui; 🎜>
2022-10-29 21:40:38.407 ERROR   services/tools.go:35    下载协程结束: 63
2022-10-29 21:40:38.407 ERROR   services/tools.go:35    下载协程结束: 64
2022-10-29 21:40:38.407 ERROR   services/tools.go:35    下载协程结束: 65
2022-10-29 21:40:38.407 ERROR   services/tools.go:35    下载协程结束: 65
2022-10-29 21:40:38.408 ERROR   services/tools.go:35    下载协程结束: 66
2022-10-29 21:40:38.408 ERROR   services/tools.go:35    下载协程结束: 67
Kod pembaikan adalah seperti berikut:

Atas ialah kandungan terperinci Penjelasan terperinci tentang masalah ralat tambah apabila Go mempunyai konkurensi yang tinggi!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam