- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Bạn luôn có thể thấy mọi người trên Internet nói rằng go đi kèm với tính năng phát hiện bế tắc. Miễn là xảy ra bế tắc, bộ thực thi có thể phát hiện ra nó và thoát ra kịp thời, do đó go sẽ không gặp rắc rối bởi các vấn đề bế tắc.
Điều này cho thấy hiệu quả của việc truyền đạt kiến thức truyền miệng đang bị đặt dấu hỏi hàng ngày, đồng thời nó cũng một lần nữa chứng minh giá trị vàng của câu nói không có viên đạn bạc.
Điểm chết của câu nói này là tuy sai nhưng không sai hoàn toàn, dù đúng hay sai thì người ta rất dễ bị mất khả năng phán xét mong đợi.
Tôi sẽ không giải thích thêm về tắc tắc.
gói nhập chính ( "fmt" ) func main() { c := make(chan int, 1) fmt.Println(<-c) }
Mã này sẽ gây ra lỗi đóng quy tắc cho golang:
goroutine 1 [chan get]: main.main() /tmp/deadlock.go:9 +0x32 thoát trạng thái 2
Tại sao ví dụ này bị khóa? nhận.
Điều này cho thấy rằng cờ vây có tính năng phát hiện quy tắc. loại tắc tắc thì bạn đã hoàn thành sai:
gói nhập chính ( "fmt" "time" ) func main() { c := make(chan int, 1) for { go func() { fmt.Println(<-c) }() time.Sleep(10 * time.Mili giây) } }
Theo Ví dụ 1, chúng tôi có thể biết rằng nếu một chan không có người gửi thì tất cả người nhận sẽ bị chặn trong ví dụ. của chúng ta, các coroutine này sẽ bị chặn vĩnh viễn.
Thực tế là không thể, chương trình này sẽ tiếp tục chạy cho đến khi hết bộ nhớ:
Có đủ thời gian để thực hiện phát hiện tắc tắc, vì mặc dù 10 mili giây là ngắn không đáng kể đối với con người, Nhưng nó khá dài để chạy golang và chúng tôi liên tục tạo các coroutine để đáp ứng tất cả các điều kiện sau đó.
Thử nghiệm so sánh góc từ, một phỏng đoán hợp lý tại thời điểm này là chính coroutine dữ liệu đã được xử lý Vì vậy, chúng tôi kiểm tra lại:
package main import ( "fmt" "time" ) func main() { c := make(chan int, 1) go func() { for { fmt.Println("Xin chào từ trẻ trẻ.") time.Sleep( 100 * thời gian.Milli giây) } }() <-c }
Mã này cũng sẽ không báo lỗi và chương trình sẽ tiếp tục xuất ra Xin chào cho đến khi bạn chấm dứt quá trình này theo cách thủ công công hoặc tắt máy tính. hiện quy tắc.
Có vẻ như việc phát hiện bế tắc của Go thường xuyên "thất bại", đây là một điều rất đáng sợ, nhất là sau khi bạn tin vào câu nói đầu bài và thả mình vào mã, chỉ cần nghĩ rằng không có lỗi nào được báo cáo là Không có vấn đề.
Thực sự không thành công khi nói rằng đây là một "sự cố". có thể giải thích một số đoạn văn bản.
Trước hết, chúng ta có thể chia các loại coroutine thành hai. coroutine do người dùng tạo, bao gồm các coroutine do người dùng chính tạo và tất cả các coroutine được sử dụng. được tạo bởi chuẩn thư viện/thư viện. loại rất sơ bộ và có nhiều điểm khác biệt trong mã thực tế, nhưng trợ giúp vật thể cụ thể được hiểu là không có vấn đề đề gì.
Biết phạm vi phát hiện, chúng tôi cũng cần biết nội dung phát hiện - nói cách khác, trong những trường hợp chúng tôi có thể đánh giá rằng một coroutine nhóm đã được đóng tắc? bất kỳ sự kiện nào hoặc chặn một số chan sẽ không bao gồm dữ liệu.
Thời gian phát hiện thực tế có phần phản ánh trực giác. Nói cách khác, việc làm Phát triển quá trình kích hoạt nhiều liên kết đến các luồng của hệ điều hành hơn là goroutine.
Vì vậy, miễn là vẫn còn một coroutine có thể tiếp tục chạy thì ngay khi 99999 coroutine khác bị khóa thì tính năng phát hiện bế tắc Thread thì không phải đang bế tắc, điều đó có thể giải quyết tại sao bộ đếm thời gian chưa được kích hoạt và hệ thống lệnh gọi chờ không phải là bế tắc). Thông thường, phần phụ coroutine ở ví dụ 3 có thể chạy bình thường nên các coroutine khác sẽ không báo lỗi ngay khi chúng bị khóa.
Có hai trường hợp lệ ngoại lệ đối với việc phát hiện:
Một số người có thể cho rằng đây là lỗi hoặc sai sót trong thiết kế và nên hương vàng báo cáo sự cố, nhưng đây không phải là error! Đó chỉ là một cách nhìn khác về vấn đề.
Mô tả chính thức hơn về cách tiếp cận mà đi áp dụng là "liệu chương trình có thể đạt được tiến bộ trong thời gian dự kiến kiến hay không." Theo Tiêu chuẩn này, miễn phí vẫn còn coroutine của người dùng đang hoạt động, điều đó có nghĩa là "toàn bộ chương trình" không thành công bế tắc - trong Go, việc đánh giá xem có gây ra lỗi bế tắc hay không dựa trên toàn bộ chương trình và dự đoán thông tin thường xuyên của chúng ta tiêu chí là tất cả cả coroutine của người dùng Không có vấn đề gì nếu quá trình này có thể "tiến bộ trong thời gian yêu cầu dự kiến". Fatal hơn.
Hơn nữa, công việc phát hiện đáp ứng yêu cầu sau rất phức tạp để thực hiện và dự kiến sẽ tiêu tốn nhiều Vì vậy, hãy chọn cái trước, tuy nhiên cái trước không thể giải quyết mọi vấn đề nhưng nó vẫn có thể ngăn chặn một số vấn đề tắc tắc trong đoạn đầu.
Tuy nhiên, những người coi việc phát hiện bế tắc là cầu lửa dầu rắn sẽ không gặp có thể:
Vì vậy, việc phát hiện tắc tắc chỉ có thể giúp ích cho bạn một lần chứ không thể dùng làm cọng cỏ cứu mạng.
Mã nguồn phát tắc tắc nằm trong chức năng checkdead của "src/runtime/proc.go".
Vì báo cáo lỗi không thể giải quyết được mọi vấn đề nên chúng tôi có thể sử dụng bất kỳ công cụ nào khác để xác định quy tắc dữ liệu có xảy ra hay không?
Trên thực tế, không có cách nào tốt. quả.
Ví dụ: if if theprogram of your bạn thường yêu cầu 1.000 coroutine thì 2.000 coroutine có thể không phải là vấn đề, nhưng chắc chắn có điều gì đó không ổn với 20.000 coroutine.
Cho dù đó là dữ liệu hay dấu vết đi kèm với Go hay giám sát hiệu suất của thứ ba, những điểm không mong muốn đều có thể dễ dàng được phát hiện. Khó khăn là làm thế nào để xác thực cụ thể có thể xác định vấn đề. đưa ra những bế tắc có thể xảy ra theo hướng giải quyết vấn đề là đủ. hiện trực tiếp nhất của bế tắc là coroutine Leak.
If cố định số lượng coroutine bị bế tắc hoặc tốc độ tạo các coroutine bị bế tắc rất chậm thì sẽ khó tìm ra vấn đề trong giám sát dữ liệu. Phản hồi để xác định dữ liệu có quy tắc hay không.
Ngoài ra, goleak, một thư viện do Uber phát triển để phát hiện rò rỉ coroutine, cũng có thể giúp ích, nhưng những thiếu sót như nhau.
Cách thứ hai được sử dụng go trace hoặc debugger dlv để xem coroutine khi chạy. khả năng xảy ra coroutine tắc tắc là tương đối cao. Khóa chéo trong cuộc gọi của các coroutine khác nhau hay không.
Thứ nhất là cần phải lấy thông tin ngăn cuộc gọi khi chương trình đang chạy, điều này sẽ ảnh hưởng đến hiệu suất của chương trình. Các thành viên cài đặt thường phải tự thực hiện nếu coroutine có số lượng lớn. thì công việc phân tích sẽ trở nên cực kỳ khó khăn.
Hơn nữa, công việc có nhiều chức năng khóa trong ngăn cuộc gọi không nhất thiết kế có nghĩa là tắc quy, có thể chỉ là sự thật cạnh tranh về khóa rất nghiêm ngặt.
Có một khối hồ sơ trong dấu vết, có thể đếm bất kỳ chức năng nào bị chặn nếu. bạn đã tìm thấy số lượng lớn khóa, chức năng liên quan đến lựa chọn và chức năng vận hành liên quan đến chan thì khả năng sẽ hoàn thành quy tắc rất cao.
Tuy nhiên, giống như Phương án 2, Phương án 3 vẫn chưa chắc chắn 100% rằng có vấn đề và vẫn cần được phân tích dựa trên trên mã thực tế. định nghĩa. dấu vết sẽ không thể ghi lại được nhiệm vụ hiện tại.
Kết luận cuối cùng là không có viên đạn bạc. Ngăn chặn các vấn đề trước khi viết mã.
Hãy quay lại lần sau để chúng ta đạt được kết quả tốt nhất Những tuyên bố có thể bị sai lệch chỉ bằng một chút thử nghiệm vẫn còn phổ biến cho đến ngày này, điều này thật đáng kinh ngạc ngạc nhiên.
Rất khó để sử dụng súng bạc xuất hiện trong ngành công nghiệp phần mềm, vì vậy việc thử nghiệm thực hành nhiều hơn có có thể giúp bạn tránh bị bẫy và nghỉ việc sớm hơn.
Nếu bạn muốn biết CFSDN hoặc . tiếp tục duyệt các bài viết liên quan.
Tôi là một lập trình viên xuất sắc, rất xuất sắc!