Tại sao tôi nên biết lập trình đồng thời?


17

Lập trình đồng thời khá khó khăn với tôi: ngay cả việc nhìn vào một slide cơ bản có vẻ thách thức đối với tôi. Có vẻ rất trừu tượng.

Những lợi ích để biết tốt các khái niệm lập trình đồng thời là gì? Nó sẽ giúp tôi trong lập trình thường xuyên, tuần tự? Tôi biết có một sự hài lòng để hiểu làm thế nào các chương trình của chúng tôi hoạt động, nhưng những gì khác?


3
Tôi nghĩ rằng đó là một vấn đề khó khăn, nhưng có thể trở nên khó hiểu nếu bạn chỉnh sửa tất cả nội dung cá nhân (mặc dù lập trình đồng thời khá khó khăn với mọi người ) và yêu cầu các giá trị kỹ thuật cụ thể của các khái niệm.
yannis

1
Những lợi ích nên khá rõ ràng. Bạn có thể viết các chương trình có thể tận dụng tất cả các cải tiến hiệu suất có sẵn thông qua phân chia công việc mà lập trình đồng thời cung cấp. Nó không dễ dàng cho bất cứ ai. Đó là một khái niệm rất thách thức ngày nay.
Giàn khoan

3
Chúng tôi không thể giúp bạn có động lực để học một cái gì đó, nhưng câu hỏi chung về lý do tại sao một người nên biết về đồng thời là đủ chủ đề.

2
Tôi biết lập trình đồng thời. Tôi có thể nói rằng slide bạn cung cấp không giúp hiểu được. Thay vào đó, hãy đến một bữa tiệc với các triết gia ăn uống .
mouviciel

1
Thư giãn, ngay cả những khó khăn lớn nhất cũng gặp khó khăn: notifyit.com/articles/article.aspx?p=1193856
SK-logic

Câu trả lời:


32

Đây là một động lực nhanh chóng và dễ dàng: Nếu bạn muốn viết mã cho bất cứ thứ gì ngoại trừ các hệ thống nhỏ nhất, yếu nhất, bạn sẽ viết mã đồng thời.

Bạn muốn viết cho đám mây? Các trường hợp tính toán trong đám mây là nhỏ. Bạn không có được cái lớn, bạn có được nhiều cái nhỏ. Đột nhiên ứng dụng web nhỏ của bạn là một ứng dụng đồng thời. Nếu bạn thiết kế nó tốt, bạn có thể ném vào nhiều máy chủ hơn khi bạn có được khách hàng. Khác, bạn phải tìm hiểu làm thế nào trong khi cá thể của bạn có mức tải trung bình được chốt.

OK, bạn muốn viết ứng dụng máy tính để bàn? Mọi thứ đều có CPU lõi kép trở lên. Ngoại trừ những máy móc ít tốn kém nhất. Và những người có máy móc ít tốn kém nhất có lẽ sẽ không dùng đến phần mềm đắt tiền của bạn, phải không?

Có lẽ bạn muốn làm phát triển di động? Này, iPhone 4S có CPU lõi kép. Phần còn lại sẽ không bị bỏ lại phía sau.

Trò chơi điện tử? Xbox 360 là một hệ thống đa CPU và PS3 của Sony về cơ bản là một hệ thống đa lõi.

Bạn không thể thoát khỏi chương trình đồng thời trừ khi bạn đang giải quyết những vấn đề nhỏ nhặt, đơn giản.

Cập nhật năm 2016 : Lặp lại hiện tại của Raspberry Pi $ 35 được xây dựng xung quanh hệ thống lõi tứ trên chip dành cho điện thoại di động. Những tiến bộ kịch tính trong AI đã được thực hiện một phần nhờ vào sự sẵn có của card đồ họa cao cấp như các công cụ tính toán song song.


1
Trong khi tôi đồng ý về nguyên tắc, để nói rằng Everything has a dual-or-more-core-CPU. Except the least expensive machines.có vẻ hơi vô lý. Rất nhiều người có máy lõi đơn, không phải vì nó rẻ, mà vì họ hài lòng với những gì họ có và không cần phải nâng cấp. Điều đó nói rằng, suy nghĩ về mặt đồng thời cũng sẽ giúp bộ lập lịch trên hệ thống một lõi, do đó, sẽ không lãng phí nỗ lực ở bất cứ nơi nào bạn có thể sử dụng đa nhiệm được ưu tiên, (đó về mọi môi trường đa nhiệm mà hầu hết các nhà phát triển sẽ tiếp xúc với, những ngày này).
một CVn

1
ok - đó là một chút cường điệu, nhưng phần cứng mới có xu hướng áp đảo là đa lõi. Tôi không thấy điều đó sẽ biến mất. Vì vậy, nếu bạn là một sinh viên ngày nay nghĩ về công việc bạn sẽ làm một cách chuyên nghiệp trong tương lai, có thể an toàn khi cho rằng bạn sẽ làm việc trên các hệ thống đa lõi.
ObscureRobot

Tôi tự hỏi nếu tôi không đồng ý với câu trả lời của bạn nhiều như bạn sẽ không đồng ý với lol của tôi;)

1
Cách tôi đọc nó, có một hạt nhân tương tự như những gì chúng ta đang nói, @ acidzombie24. Tôi đang nói rằng một nhà phát triển nên biết cách xử lý đồng thời bởi vì nó sẽ ở khắp mọi nơi. Bạn đang nói rằng bạn không cần phải giỏi lập trình miễn là bạn ... tránh những cạm bẫy của các hệ thống đồng thời :)
ObscureRobot

Tôi đồng ý rằng rất hữu ích khi biết về đồng thời, nhưng không đồng ý bạn chỉ có thể thoát khỏi nó vì "những vấn đề nhỏ, đơn giản". Bạn có thể thoát khỏi sự đồng thời rất nhiều, ngay cả trong các hệ thống không tầm thường, ví dụ nếu bạn dựa vào các khung và máy chủ ứng dụng hiện có. Khi cơ sở hạ tầng đã sẵn sàng, tôi có thể là một nhà phát triển cơ sở viết các dịch vụ mới cho một ứng dụng web và hầu như không biết gì về đồng thời hoặc song song.
Andres F.

21

Từ năm 1970 đến khoảng 2002 bộ xử lý tăng gấp đôi tốc độ cứ sau 18 tháng. Vì vậy, là một lập trình viên, tất cả những gì bạn phải làm là chờ đợi và chương trình của bạn sẽ diễn ra nhanh hơn. Vấn đề là khoảng năm 2002 các quy tắc đã thay đổi. Bây giờ họ không tạo ra các bộ xử lý nhanh lớn hơn, họ đang tạo ra các bộ xử lý chậm nhỏ hơn mà đưa chúng ra theo nhóm. Máy tính tôi đang làm việc hiện có 4 lõi và Chips có tới 8 lõi (và 4 luồng trên mỗi lõi) tồn tại. Không lâu nữa chúng ta sẽ có chip với nhiều lõi hơn.

Vì vậy, nếu bạn viết một chương trình hoàn toàn không đồng thời, bạn sẽ thấy rằng bạn đang sử dụng 1 lõi hoặc luồng, nhưng phần còn lại của CPU đang ngồi đó không làm gì cả. Vì vậy, nếu bạn có 16 nhân 1 sẽ chạy chương trình của bạn và 15 nhân khác đang ngồi ở đó!

Vấn đề với sự tương tranh là nó không mang tính quyết định. Điều đó có nghĩa là bạn không biết chính xác thứ tự các luồng khác nhau sẽ làm gì. Các lập trình viên truyền thống đã cố gắng giải quyết điều này bằng cách sử dụng các khóa và tương tự. Điều này đã dẫn đến một LOT đau đớn. Có một số dạng trạng thái có thể thay đổi mà nhiều hơn một chủ đề có thể truy cập tự do thường là một công thức cho nỗi đau và heisnebugs!

Cuối xu hướng là chuyển sang các ngôn ngữ chức năng kiểm soát chặt chẽ trạng thái có thể thay đổi. Có hai cách cơ bản mà các ngôn ngữ chức năng xử lý đồng thời. Đầu tiên là bằng cách sử dụng tin nhắn đi qua. Điều này được thể hiện tốt nhất bởi Erlang. Trong Erlang nói chung không có trạng thái Chia sẻ giữa các quy trình. Họ liên lạc không phải bằng cách chia sẻ bộ nhớ mà là tin nhắn qua của tôi. Điều này sẽ có ý nghĩa với bạn khi chúng tôi đang làm điều đó ngay bây giờ. Tôi đang gửi thông tin này cho bạn bằng cách gửi tin nhắn cho bạn chứ không phải bạn nhớ nó ra khỏi não tôi! Bằng cách chuyển sang tin nhắn vượt qua hầu hết các lỗi khóa chỉ cần biến mất. Ngoài ra, tin nhắn có thể được truyền qua mạng cũng như trong một nút.

Phương pháp khác là STM, viết tắt của Bộ nhớ phiên mã phần mềm, Điều này hiện diện trong clojure và Haskell (và các phương thức khác). Trong bộ nhớ STM được chia sẻ nhưng thay đổi chỉ có thể được thực hiện thông qua một giao dịch. Vì những người trong Cơ sở dữ liệu đã tìm ra tất cả những thứ này vào những năm 1970, khá dễ dàng để đảm bảo rằng chúng tôi hiểu đúng.

Trên thực tế tôi đã đơn giản hóa một chút, Clojure và Haskell đều có thể thực hiện chuyển tin nhắn và Erlang có thể thực hiện STM.

Tuyên bố miễn trừ trách nhiệm Tôi là tác giả của Lập trình dịch vụ web với Erlang , sẽ được phát hành sớm trong vài tuần tới.


1
@Zachary K: có những cách tiếp cận pha trộn ngôn ngữ chức năng với ngôn ngữ bản địa để các phần chuyên sâu tính toán được thực hiện bằng ngôn ngữ bản địa nhưng chúng cung cấp giao diện có thể được sử dụng bởi một máy chủ được viết bằng ngôn ngữ chức năng?
rwong

Không chắc chắn 100%, nhưng cả Clojure và Scala đều tồn tại trên JVM, vì vậy đó là nơi tôi sẽ bắt đầu. Có lẽ hãy nhìn vào khuôn khổ Akka. Tôi đã không sử dụng nó nhưng đã nghe một cuộc nói chuyện về Akka một thời gian trước và có vẻ như nó có thể khá tuyệt. Hiện tại tôi đang làm Erlang và Javascript đang chiếm phần lớn thời gian của tôi!
Zachary K

1
@rwong: .NET cho phép lập trình viên sử dụng C # hoặc các ngôn ngữ phi chức năng khác cho một số phần trong ứng dụng của họ và F #, một ngôn ngữ chức năng, cho các ngôn ngữ khác.
Kevin - Tái lập Monica

5

Bởi vì đồng thời có thể nổ tung trong khuôn mặt của bạn khi bạn mong đợi nó ít nhất ...


4
+10000000000000000000000000000000000000000

8
Đồng thời là điều tra mới của Tây Ban Nha [/ python] [như trong: không ai mong đợi ...]
ObscureRobot

1
@ObscureRobot vui gấp đôi! (không cần giải thích :-p)
fortran

4

Nguyên tắc đầu tiên của lập trình đồng thời là "Thật khó". Quy tắc thứ hai của lập trình đồng thời là "Nó. Khó." !! !!

Nghiêm túc mà nói, có hai cách tiếp cận phổ biến để lập trình đồng thời, đa luồng và đa xử lý. Đa xử lý là dễ hiểu nhất vì nó chỉ có nghĩa là có nhiều phiên bản của một tiến trình đang chạy để hoàn thành một nhiệm vụ. Điều này khá dễ thực hiện trên các hệ thống dựa trên Unix thông qua các cuộc gọi đến fork / tham gia, nhưng không dễ dàng như vậy trên các hệ thống Windows.

Đa luồng có lẽ là cách tiếp cận mà hầu hết mọi người nghĩ đến khi nói về đồng thời. Không khó để bắt đầu nhiều luồng trong một ứng dụng, nhưng ma quỷ nằm trong các chi tiết. Bạn cần phối hợp chia sẻ dữ liệu giữa các luồng (thường sử dụng khóa) có thể dẫn đến bế tắc hoặc dữ liệu ở trạng thái không hợp lệ. Bạn cũng cần hiểu làm thế nào để giao tiếp giữa các luồng bằng cách sử dụng các khái niệm như semaphores, biến điều kiện, v.v.

Lợi thế cho tất cả điều này là một khi bạn hiểu nó, bạn có thể sử dụng hiệu quả hơn phần cứng cơ bản. Ngày nay, chuẩn mực cho bộ xử lý có nhiều lõi. Bằng cách sử dụng lập trình đồng thời, bạn có thể làm cho các lõi này hoạt động cho bạn và ứng dụng của bạn sẽ được cải thiện tốc độ.

Nhược điểm là bạn phải bắt đầu suy nghĩ về cách bạn sẽ chia ứng dụng của mình thành các phần nhỏ có thể chạy trên các luồng khác nhau. Điều này khó hơn nhiều so với âm thanh. Ngoài ra, các giải pháp đồng thời cao có thể gây khó xử cho đơn vị kiểm tra vì thứ tự thực hiện ít mang tính quyết định.

Ngày nay, hầu hết các ngôn ngữ đều có sự trừu tượng hóa trên hầu hết các nguyên thủy đồng thời để làm cho cuộc sống dễ dàng hơn một chút. Ví dụ, .NET 4 xuất xưởng với Thư viện song song tác vụ giúp cuộc sống dễ dàng hơn một chút. Ở vùng đất Java, họ đã có gói Đồng thời .


1
Nó nhận được các đơn đặt hàng lớn nếu bạn chạy khỏi ổ khóa càng nhanh càng tốt. Sử dụng STM hoặc diễn viên và tất cả những gì bạn nói sẽ biến mất. Tất nhiên, điều đó có nghĩa là chuyển từ Java sang các ngôn ngữ như Scala, Erlang hoặc Clojure. (mặc dù tôi sẽ cho rằng đây cũng là một điều tốt)
Zachary K

@Zachary: Nó có thể là một điều tốt, nhưng nếu bạn làm việc trong một cửa hàng .NET, chẳng hạn, nó không thực tế. STM có thể là một tùy chọn trong tương lai, nhưng hiện tại nó không phải là một tùy chọn trong các ngôn ngữ chính.
Sean

Clojure chạy trên .net và có F #. Tôi cá là cũng có triển khai STM cho C #.
Zachary K

3

Gần đây tôi đã có một nhiệm vụ rất thú vị để thực hiện trong đó đa xử lý đã cứu tôi. Về cơ bản, tôi đã phải thực hiện rất nhiều yêu cầu đến một vài máy chủ riêng biệt, xử lý một lượng dữ liệu rất nhỏ, nhưng nhiều yêu cầu.

Làm việc với PHP, tôi đã làm mọi thứ theo cách cũ và thời gian tốt nhất tôi có được sau vài giờ làm việc dẫn đến ~ 120 giây để chạy thử nghiệm nhất định (nhiều yêu cầu + độ trễ mạng + không đồng bộ)

Nhưng điều đó gần như không đủ so với những gì tôi cần và sau khi thất bại thảm hại với đa xử lý PHP, tôi chuyển sang Python.

Sau một vài giờ, tôi đã có một kịch bản đa xử lý Python đang chạy trong 20 giây và sau một chút loay hoay với thời gian chờ và không. trong số các chủ đề được sử dụng, tôi đã giảm xuống còn 10 giây .

Điều này là cho một trang web được viết 100% bằng PHP, ngoại trừ một tập lệnh Python 100 dòng duy nhất. Và toàn bộ điều đang làm việc hoàn hảo.

Kết luận của tôi sẽ là ngay cả khi nó không giúp bạn hàng ngày, bạn có thể gặp phải tình huống trong đó biết ít nhất những điều cơ bản về lập trình đồng thời sẽ giúp bạn rất nhiều.

Chúc may mắn, và mã hóa hạnh phúc!

PS: Tôi không cố gắng bash PHP, nhưng PHP đơn giản không phải là công cụ phù hợp cho công việc trong tay.

PS2: Biết một công nghệ mới, hoặc một cách làm mới có thể mở ra cánh cửa đến một thế giới hoàn toàn mới.


2

Nếu bạn thực hiện bất kỳ loại phát triển web nào, đồng thời sẽ phát huy tác dụng, ít nhất là với hầu hết các ngôn ngữ. Ví dụ, tôi sử dụng mùa xuân để phát triển web và mỗi yêu cầu mới xuất hiện dưới dạng luồng riêng. Do đó, nếu bất kỳ yêu cầu nào kết thúc truy cập vào một đối tượng chia sẻ, trong đó trạng thái có thể được thay đổi của một biến, đồng thời là một yếu tố rất lớn và phải được xem xét. Nếu không, thì dữ liệu có thể được chỉnh sửa theo những cách không thể đoán trước và tham nhũng dữ liệu có thể dẫn đến. Không quan trọng để biết mọi chi tiết cuối cùng về đồng thời nhưng việc học từng phần rất quan trọng để hiểu rõ hơn về lập trình ứng dụng web, nếu bạn đang làm việc trên các ứng dụng máy tính để bàn, có thể nó không quá quan trọng trừ khi bạn cần chạy nhiều luồng


-1

Tìm hiểu cái nhìn sâu sắc của hệ điều hành. Đọc mã nguồn của bộ lập lịch và trình điều khiển thiết bị sẽ giúp ích; chúng chắc chắn đồng thời.


2
Đồng thời cho các lập trình viên thường đi cho các chương trình của riêng bạn chạy trong nhiều trường hợp.

Tôi đã cố gắng nhấn mạnh rằng bạn không thể viết chương trình đồng thời của riêng mình mà không biết chi tiết về thuật toán lập lịch của nhân hệ điều hành.
jj1bdx

Tại sao không? Nếu bạn sử dụng các cơ chế khóa chính xác, thuật toán lập lịch của hệ điều hành là không quan trọng.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.