2012-02-07 12 views
5

Chúng tôi đang phát triển một ứng dụng máy chủ c nhỏ. Ứng dụng máy chủ thực hiện một số xử lý dữ liệu và trả lời lại cho máy khách. Để giữ cho phần xử lý dữ liệu có thể cấu hình và linh hoạt, chúng tôi quyết định đi để viết kịch bản và dựa trên sự sẵn có của các mô-đun sẵn sàng khác nhau, chúng tôi quyết định đi cho Python. Chúng tôi đang sử dụng api Python-C để gửi/nhận dữ liệu giữa c và python.Vấn đề đồng thời api Python-C

Các thuật toán làm việc gì đó như thế này: -

  1. Server nhận được một số dữ liệu từ khách hàng, dữ liệu này được lưu trữ trong một từ điển được tạo ra trong c. Từ điển được tạo bằng hàm apD PyDict_New(); từ C. Dữ liệu đầu vào được lưu trữ như một cặp giá trị khóa trong từ điển bằng cách sử dụng hàm api PyDict_SetItemString();
  2. Tiếp theo, chúng tôi thực thi kịch bản python PyRun_SimpleString(); truyền tập lệnh dưới dạng tham số. Tập lệnh này sử dụng từ điển được tạo trong c. Xin lưu ý, chúng tôi tạo từ điển được tạo bằng c, có thể truy cập được vào tập lệnh bằng cách sử dụng phương thức PyImport_AddModule(); và PyModule_AddObject();
  3. Chúng tôi lưu trữ kết quả xử lý dữ liệu trong tập lệnh dưới dạng cặp giá trị khóa trong cùng một từ điển được tạo ở trên. Sau đó, mã c có thể truy cập vào biến kết quả (cặp khóa-giá trị) sau khi tập lệnh đã được thực thi.

Vấn đề Vấn đề chúng tôi đang phải đối mặt là trong trường hợp yêu cầu đồng thời đến từ khách hàng khác nhau. Khi có nhiều yêu cầu đến từ các khách hàng khác nhau, chúng tôi có xu hướng phản đối các ngoại lệ về số lượng tham chiếu. Xin lưu ý rằng, đối với mỗi yêu cầu cho người dùng, chúng tôi sẽ tạo một từ điển độc lập cho người dùng đó. Để khắc phục vấn đề này, chúng tôi đã thực hiện cuộc gọi đến PyRun_SimpleString(); trong PyEval_AcquireLock(); và PyEval_ReleaseLock() ;, nhưng làm điều này đã dẫn đến việc thực thi tập lệnh là một cuộc gọi chặn. Vì vậy, nếu một tập lệnh mất nhiều thời gian để thực thi, tất cả những người dùng khác cũng đang chờ phản hồi.

Bạn có thể đề xuất cách tiếp cận tốt nhất có thể hoặc đưa ra gợi ý đến nơi chúng tôi đang đi sai. Vui lòng ping cho tôi để biết thêm thông tin.

Mọi trợ giúp/hướng dẫn sẽ được đánh giá cao.

Trả lời

1

Có thể bạn đang thiếu một trong các cuộc gọi được đề cập trong this answer.

+0

Cảm ơn bạn đã tham khảo Jane. Ngẫu nhiên, tôi đã thực hiện các cuộc gọi đến các chức năng đó, nhưng nó vẫn không hoạt động. – Will

1

Bạn có lẽ nên đọc http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock Vấn đề của bạn được giải thích trong đoạn đầu tiên.

Khi bạn có được GIL, hãy làm như vậy xung quanh thao tác trực tiếp đối tượng Python của bạn. Các cuộc gọi đến PyRun_SimpleString sẽ xử lý GIL nội bộ và sẽ cung cấp cho nó lên trên hoạt động lâu dài hoặc chỉ là mọi hướng dẫn X. Nó S NOT KHÔNG thực sự đa luồng, tuy nhiên.

Edit:

Bạn cần để có được khóa và bạn cần phải đảm bảo rằng Python biết nó ở trong tình trạng chủ đề khác nhau:

// acquire the lock and switch thread state 
PyEval_AcquireLock(); 
PyThreadState_Swap(perThreadState); 

// execute some python code 
PyEval_SimpleString("print 123"); 

// clear the thread state and release the lock 
PyThreadState_Swap(NULL); 
PyEval_ReleaseLock(); 
+0

Xin chào Tom, cảm ơn câu trả lời. Bạn có thể vui lòng giải thích cho thực tế rằng nó sẽ "KHÔNG" thực sự đa luồng?Bạn có nghĩa là để nói rằng các kịch bản không bao giờ có thể thực hiện song song? – Will

+0

Có một khóa thông dịch toàn cục - chỉ một lệnh bytecode python sẽ thực thi tại một thời điểm bất kể có bao nhiêu luồng. Các chức năng chạy dài như mở tập tin giải phóng khóa tạm thời trong khi chúng đang thực thi, và trình thông dịch python định kỳ từ bỏ khóa, nhưng cuối cùng trong một quá trình mã byte bytecode được thực thi serially. –

+0

Cảm ơn Tom. Đánh giá cao thời gian của bạn cho câu trả lời. Vui lòng xác nhận điều này: Nếu PyRun_SimpleString đang thực hiện trong 2 (hoặc có thể n) riêng biệt "c" chủ đề, nó sẽ chăm sóc của GIL chính nó và do đó tôi không cần phải chặn hoặc khóa trước khi thực hiện cuộc gọi đến PyRun_SimpleString từ bất kỳ chủ đề. – Will

1

Tôi đề nghị bạn điều tra các module multiprocessing.