2009-10-06 6 views
8

Sau khi đọc về việc sử dụng react trong các diễn viên ở Scala, tôi nghĩ rằng react sẽ chia sẻ cùng một chuỗi cho rằng không có nhiều yêu cầu đang chờ xử lý của react. Nó không có vẻ như vậy.Khi nào các chủ đề được tạo cho các phản ứng của diễn viên Scala?

import scala.actors.Actor 
import scala.actors.Actor._ 

class SleepyReactor extends Actor { 
    def act() { 
     loop { 
      react { 
       case x => { 
        println("reacting to %s on thread %s".format(x, Thread.currentThread.getName)) 
        Thread.sleep(1000) 
        println("done with " + x) 
       } 
      } 
     } 
    } 
} 
val sleepyOne = new SleepyReactor 
sleepyOne.start 
sleepyOne ! "first" // runs on thread-5 

// wait until completion 

sleepyOne ! "second" // runs on thread-3 

Ai đó có thể giải thích tại sao những react 's đang chạy trên chủ đề khác nhau và khi một chủ đề mới được tạo ra cho một diễn viên với react?

Tôi đọc ở đâu đó react là sự kiện dựa trên và tôi đã làm điều đó có nghĩa là "tác nhân phản ứng" đã chia sẻ một chuỗi và nếu một "phản ứng" "các tác nhân phản ứng" khác sẽ được xếp hàng cho đến khi lần đầu tiên được thực hiện. Giờ tôi nghĩ mình sai rồi. Làm thế nào để làm việc này, và làm thế nào là nó khác với nhận được?

+0

cũng thấy http://stackoverflow.com/questions/1251666/scala- diễn viên-nhận-vs-phản ứng –

Trả lời

9

Đúng là đối với một diễn viên dựa trên sự kiện thuần túy, mã phản ứng của nó chạy trên cùng một luồng với mã gửi thư. Tuy nhiên, trong Scala, vì nó không được mong muốn để chặn một sợi khi một diễn viên gọi một hoạt động chặn bên trong mã phản ứng của nó và để thống nhất các sự kiện dựa trên sự kiện và diễn viên (có thể soạn chúng), cả hai loại diễn viên sử dụng cùng một nhóm luồng nhưng các tác nhân dựa trên luồng có chủ đề riêng của họ trong khi các tác nhân dựa trên sự kiện chia sẻ các luồng dựa trên hàng đợi nhiệm vụ. Để biết chi tiết, vui lòng xem Actors that Unify Threads and Events bởi Philipp Haller và Martin Odersky

3

Thư viện trình lập lịch sử dụng một nhóm luồng để kiểm soát việc thực hiện các tác nhân. Tôi không biết các chi tiết cụ thể của logic nó sử dụng, nhưng, với tôi, nó sẽ có vẻ tự nhiên để mong đợi nó:

  • Initialize với hơn một thread trong hồ bơi, như các ứng dụng đa luồng rất có khả năng để sử dụng nhiều hơn một thead.

  • Chọn chủ đề được sử dụng với diễn viên chờ đợi theo cách xếp hàng - các chuỗi được giải phóng vào cuối hàng đợi và lấy từ đầu hàng đợi.

Ngoài ra, tôi giả định một số chủ đề được sử dụng để xử lý việc lên lịch cũng như gửi thư.

5

Đừng giả định một chuỗi riêng biệt cho mỗi Diễn viên. Máy móc Scala tạo ra một nhóm các chủ đề công nhân và chỉ phát triển hồ bơi đó nếu kích thước của các diễn viên 'bị chặn' lớn hơn kích thước hồ bơi. Khi diễn viên của bạn gọi receive, nó ở trạng thái bị chặn cho đến khi nhận được tin nhắn.

4

Để xem hiệu ứng được mô tả trong các câu trả lời trước, bạn cần tạo nhiều hơn hai chuỗi. Chương trình mẫu này tạo ra 100 luồng với nhận và 100 luồng có phản ứng.

Khi bạn chạy nó, bạn có thể thấy rằng các tác nhân nhận từng chiếm một chủ đề, và những người phản ứng chia sẻ một số lượng nhỏ các chủ đề. (Đó là đơn giản nhất để xem khi nào bạn sắp xếp các đầu ra.)

import scala.actors._ 
import scala.actors.Actor._ 

class ReactActor extends Actor { 
    def act { 
    loop { 
     react { 
     case 'Hello => println("React: " + Thread.currentThread) 
     } 
    } 
    } 
} 

class ReceiveActor extends Actor { 
    def act { 
    while (true) { 
     receive { 
     case 'Hello => println("Receive: " + Thread.currentThread) 
     } 
    } 
    } 
} 

object Main { 
    def main(args: Array[String]) { 
    val count = 100 
    val as = new Array[Actor](2 * count) 
    for (i <- 0 until count) { 
     as(i) = new ReactActor 
     as(count + i) = new ReceiveActor 
    } 
    for (a <- as) a.start() 
    actor { 
     println(Thread.currentThread) 
     for (a <- as) a ! 'Hello 
    } 
    } 
} 

Kết quả được sắp xếp trong một chương trình chạy điển hình:

Thread[Thread-102,5,main] 
React: Thread[Thread-102,5,main] 
React: Thread[Thread-102,5,main] 
React: Thread[Thread-102,5,main] 
... 
React: Thread[Thread-102,5,main] 
React: Thread[Thread-103,5,main] 
React: Thread[Thread-103,5,main] 
... 
React: Thread[Thread-103,5,main] 
React: Thread[Thread-104,5,main] 
React: Thread[Thread-104,5,main] 
React: Thread[Thread-104,5,main] 
... 
React: Thread[Thread-104,5,main] 
React: Thread[Thread-105,5,main] 
React: Thread[Thread-105,5,main] 
React: Thread[Thread-105,5,main] 
... 
React: Thread[Thread-105,5,main] 
Receive: Thread[Thread-1,5,main] 
Receive: Thread[Thread-10,5,main] 
Receive: Thread[Thread-100,5,main] 
Receive: Thread[Thread-101,5,main] 
Receive: Thread[Thread-11,5,main] 
Receive: Thread[Thread-12,5,main] 
Receive: Thread[Thread-13,5,main] 
Receive: Thread[Thread-14,5,main] 
Receive: Thread[Thread-15,5,main] 
Receive: Thread[Thread-16,5,main] 
Receive: Thread[Thread-17,5,main] 
Receive: Thread[Thread-18,5,main] 
Receive: Thread[Thread-19,5,main] 
Receive: Thread[Thread-2,5,main] 
Receive: Thread[Thread-20,5,main] 
Receive: Thread[Thread-21,5,main] 
...