2012-06-02 35 views
8

Tôi muốn biết liệu DWScript có khả năng sử dụng các luồng bên trong các tập lệnh hay không, vì một số công cụ không đồng bộ hóa quyền truy cập vào cấu trúc dữ liệu nội bộ của nó.DWScript có an toàn không?

+0

-1 câu hỏi này được trả lời một cách trivially bằng cách đọc tài liệu, trang đầu của trang web dự án DWScript, tìm kiếm trên web, v.v. Hãy nỗ lực trước khi đặt câu hỏi. –

+1

Nếu câu trả lời là dễ tìm, thì chắc chắn phải bỏ qua nó nhiều lần, hoặc tôi sẽ không đăng câu hỏi. – FHannes

+4

@david: nếu mọi người chỉ rtfm, sẽ không có stackoverflow :) –

Trả lời

4

Arnaud cho những điểm mấu chốt:

  • mỗi trường hợp trình biên dịch chỉ có thể được gọi từ một thread tại một thời điểm. Bạn có thể có nhiều cá thể trình biên dịch được gọi trong nhiều luồng cùng lúc, và một cá thể trình biên dịch cụ thể có thể được sử dụng từ nhiều luồng, chỉ được cung cấp một luồng sử dụng nó một thời gian.
  • mỗi chương trình được biên dịch có thể có nhiều lần thực thi, mỗi lần thực thi có thể chạy trong chuỗi riêng của nó. Ngoài ra một thực thi cụ thể có thể được sử dụng bởi một số chủ đề, chỉ cung cấp một chủ đề sử dụng nó tại một thời điểm.
  • mỗi thực thi có không gian riêng cho các biến của nó, và ngăn xếp riêng của nó, đối tượng thể hiện trên đống và về mặt kỹ thuật có thể được chia sẻ trên thực thi, không có cơ chế khóa cho điều đó, nhưng bạn có thể tự tạo.
  • công cụ tập lệnh không thực hiện bất kỳ đồng bộ hóa hoặc khóa nào khi sử dụng các lớp hoặc chức năng tiếp xúc với nó (có thể là thông qua TdwsUnit, RTTI, v.v.), Vì vậy khi chạy hành kịch bản trong bài, hãy chắc chắn bạn chỉ tiếp xúc với thread-safe thứ (đặc biệt cẩn thận về điều đó cho RTTI, vì rất nhiều các RTL & VCL là không thread-safe để bắt đầu với)

Việc chạy nhiều kịch bản lệnh tương tự như có nhiều luồng trong Delphi, mặc dù mỗi lần thực thi mới không chỉ có ngăn xếp riêng của nó (như các luồng Delphi) mà còn cả không gian biến riêng của nó (trong Delphi nó sẽ hơi giống nếu bạn có "chuỗi" var "ở khắp mọi nơi). Và các thực thi DWScript không phải nằm trong luồng riêng của chúng, chúng có thể được chuyển qua các luồng, hoặc được thăm dò và sử dụng trong một số luồng thấp hơn (giới hạn duy nhất là mỗi lần thực thi chỉ được sử dụng bởi một luồng tại một thời điểm) đã đề cập ở trên). Vì vậy, không có gì ngăn cản bạn để lộ ra một hàm sẽ sinh ra một luồng (và thực thi tương ứng) trong một hàm script, nhưng việc truyền thông qua các thực thi sẽ không thông qua các biến chia sẻ (như bạn có thể bị cám dỗ trong Delphi). , nhưng sẽ phải trải qua các hàm tiếp xúc của riêng bạn (hoặc các biến bên ngoài), trả về các giá trị (sử dụng cách tiếp cận "đánh giá", xem các bài kiểm tra đơn vị), các cá thể đối tượng "được chia sẻ" hoặc "vars toàn cầu".

Bởi "toàn cầu vars", tôi có nghĩa là các chức năng được định nghĩa trong dwsGlobalVarsFunctions.pas, có thể được sử dụng để trao đổi dữ liệu liên thực hiện. Để kích hoạt chúng, chỉ cần có một "sử dụng dwsGlobalVarsFunctions" một nơi nào đó trong dự án của bạn.

Chúng hiển thị một tập hợp các chức năng Đọc/GhiGlobalVar, cho phép lưu trữ và truy xuất các biến thể được đặt tên trên tất cả các tập lệnh được chạy trong cùng một quá trình Delphi và những lần đọc & ghi là "nguyên tử".

+1

Đẹp có DWS "cha thần" (hoặc cha mới) trong SO! :) –

+0

Khi một đối tượng TdwsProgramExecution đang được thực hiện trong một luồng, có thể một luồng khác gọi TdwsProgramExecution.EndProgram một cách an toàn không? – FHannes

+0

Không, nhưng bạn có thể gọi Dừng cho điều đó (cũng hoạt động nếu bạn thực hiện bởi Execute(), thay vì bằng tay với BeginProgram/RunProgram). Điều đó sẽ khiến kịch bản bị hủy bỏ tại cơ hội sớm nhất dưới sự kiểm soát của nó, tức là. nếu kịch bản của bạn đang chạy một hàm Delphi, nó sẽ chỉ dừng lại sau khi trở về từ hàm đó. EndProgram làm sạch và có nghĩa là để được gọi từ thread thực hiện. –

3

Thậm chí không cần thiết phải mở tài liệu DWS. :)

Chỉ cần có một cái nhìn at this StackOverflow answer by Eric:

Ví dụ, [DWS] hiện có khả năng nhiều hành thread-safe của một kịch bản được biên soạn đơn, trong khi codebase cũ được xây dựng xung quanh giới hạn rằng một tập lệnh được biên dịch có thể được thực hiện bởi chỉ một luồng tại một thời điểm.

Nói tóm lại:

  • Trình biên dịch DWS không phải là thread-safe: bạn phải tạo ra việc thực hiện ngăn xếp trong một thread (bạn không thể chia sẻ một trường hợp trình biên dịch, bạn cần một thread cho mỗi trình biên dịch);
  • Việc thực thi DWS là an toàn chỉ, nếu bạn sử dụng một cá thể thực thi cho mỗi luồng: bạn có thể chạy cùng một tập lệnh đã biên dịch trong một số luồng;
  • Giao tiếp giữa các chủ đề không có sẵn AFAIK, nhưng bạn có thể sử dụng mã Delphi nếu bạn cần đồng bộ hóa.

Tất nhiên, đây là the official documentation page about thread safety in DWS.

Bây giờ bạn có thể có nhiều hành chương trình cho một IdwsProgram được như bạn muốn, từng thực hiện sẽ sử dụng bộ nhớ cho đống & stack của nó mà thôi, cây biểu thức biên soạn được chia sẻ. Cả hai giao diện mới đều sử dụng quản lý bộ nhớ tham chiếu.

+1

Đọc điều này thông qua, tôi nhận ra rằng tôi đã biết điều này, nhưng trừ khi tôi sai, nó không hoàn toàn trả lời câu hỏi của tôi ... Tôi không muốn chạy cùng một kịch bản trong nhiều chủ đề, tôi muốn được chạy nhiều luồng bên trong một tập lệnh duy nhất ... – FHannes

+1

AFAIK cho đến nay tôi hiểu việc triển khai lớp thực hiện, không thể, theo thiết kế. Không có TThread hoặc như vậy. Khả năng duy nhất sẽ là chạy một số kịch bản bên trong một luồng cho mỗi (tất nhiên là có thể), sau đó cố gắng thực hiện với IPC hoặc mutex giữa các tập lệnh, giống như tôi đã viết ở điểm thứ 3 của tôi: có sẵn từ đầu. Tôi muốn giới thiệu kiến ​​trúc không quốc tịch, với một số cấu trúc dữ liệu được chia sẻ được tạo bởi các lớp Delphi (ví dụ: tiếp xúc bằng RTTI thành DWS). –