2011-11-21 25 views
8

Tôi đang lưu trữ một từ điển trong một phiên Django có thể truy cập bởi nhiều chủ đề. Tất cả các chủ đề có thể cập nhật từ điển, chủ đề cũng nhận được các giá trị từ điển để chạy quá trình. Tôi muốn biết phiên Django là thread an toàn hoặc tôi phải sử dụng khóa hoặc semaphores?Chủ đề phiên Django có an toàn không?

điển hình ví dụ:

Thread1: 
threadDict = request.session.get('threadDict', None) 
if threadDict['stop']: 
    #break the for loop exit the thread 
else: 
    #do some processing and update some values in thread dictionary 
    threadDict['abc'] = 0 
    request.session['threadDict'] = threadDict (Point1) 

def someFunction(): 
    #this function is used to send stop signal to thread 
    threadDict = request.session.get('threadDict', None) 
    threadDict['stop'] = True 
    request.session['threadDict'] = threadDict (Point2) 

Liệu có một cơ hội mà khi Point2 cập nhật từ điển chủ đề trong phiên ngay sau khi nó cập nhật Point1 cũng cập nhật nó, sau đó tôi stop bỏ chủ đề sẽ bị mất.

More Info

Một yêu cầu ajax bắt đầu bằng bốn chủ đề mà tải mẫu từ 4 url ​​khác nhau. Tại sao tôi sử dụng chủ đề? bởi vì tôi muốn hiển thị cho người dùng những mẫu nào hiện đang được tải xuống và những mẫu nào còn lại. Tất cả các chủ đề sẽ cập nhật trạng thái của nó trong từ điển trong phiên. Sau khi các chủ đề bắt đầu, tôi thực hiện yêu cầu ajax sau mỗi hai giây và lấy từ điển từ phiên và đọc trạng thái hiện tại của luồng. Nhưng ý tưởng này thất bại vì các chủ đề độc lập với yêu cầu và phiên của họ. Mỗi yêu cầu ajax chắc chắn có phiên của nó nhưng tôi không thể vượt qua phiên đó cho chủ đề vì khi họ bắt đầu họ độc lập với phần còn lại của thế giới (Có thể tôi có thể vượt qua nó nhưng tôi có thể không vượt qua nó nhanh chóng quá trình đang được thực hiện bởi chủ đề). do đó, để giải quyết vấn đề này, tôi chọn khung bộ nhớ cache thay vì phiên. vì bộ nhớ cache có thể truy cập được từ mọi nơi. Chủ đề lưu trữ trạng thái của họ trong từ điển và đưa trở lại vào bộ nhớ cache và sau mỗi hai giây tôi lấy từ điển từ bộ nhớ cache và đọc trạng thái. Và một điều nữa theo bộ nhớ cache kinh nghiệm của tôi không phải là chủ đề an toàn. Vì vậy, trong bốn chủ đề tôi sử dụng bốn từ điển sepratelly.

Trả lời

6

Đối tượng request.session được trả lại sẽ là một đối tượng mới cho mọi yêu cầu, truy cập cùng một bộ nhớ. Hơn nữa, chúng được nạp từ bộ nhớ tại thời gian yêu cầu và được lưu lại ở thời gian đáp ứng. Vì vậy, nếu bạn muốn chuyển thông tin từ một chuỗi dài chạy sang một yêu cầu khác, bạn cần phải lưu nó trong chuỗi dài chạy theo cách thủ công. Thật không may, điều này sẽ dẫn đến việc sửa đổi dữ liệu của cùng một phiên bị mất.

Phiên có chủ đề an toàn theo một nghĩa nào đó. Bạn sẽ không phá vỡ thông dịch viên theo cách này. Yêu cầu của bạn sẽ thấy dữ liệu phiên làm ảnh chụp nhanh của nó trên lần truy cập đầu tiên và khi lưu nó sẽ ghi đè tất cả các thay đổi đã hạ cánh kể từ thời điểm đó. Vì vậy, trạng thái phiên sẽ nhất quán, nhưng một số sửa đổi của yêu cầu có thể bị mất. Trên thực tế, thuộc tính này là phổ biến đối với hầu như mọi khung công tác - bất kỳ phiên/bộ nhớ cache nào cũng có thể được chia sẻ giữa nhiều quá trình.

+0

Nếu tôi nhớ lại chính xác, bạn có thể chỉnh sửa câu hỏi của mình và thêm thông tin vào câu hỏi đó. – Tanriol

+0

ok cảm ơn tôi đã thêm chi tiết trong câu hỏi. –

0

Các loại cơ bản trong Python nói chung là an toàn chủ đề nhờ vào global interpreter lock. Khóa này được phát hành trong một số tình huống (ví dụ khi làm I/O) để cho phép truy cập các chủ đề khác. Điều này có nghĩa là bạn (ứng dụng) sẽ phải duy trì trạng thái nhất quán trong các cuộc gọi có thể giải phóng GIL. Ví dụ về các phương pháp như vậy đang chặn hoạt động của socket.

+0

có cách nào để truy cập phiên django trong một số chức năng mà không sử dụng 'request.session' tôi muốn truy cập trực tiếp phiên không ?? –

+0

Tại sao bạn không muốn sử dụng request.session? – Krumelur

+0

tôi muốn lưu trữ trạng thái của một số ở đâu đó, như chủ đề được khởi xướng khi tôi không thể vượt qua yêu cầu một lần nữa và một lần nữa, một khi tôi bắt đầu quá trình tôi làm yêu cầu ajax để kiểm tra trạng thái lấy từ điển được lưu trữ trong phiên để biết trạng thái hiện tại của chủ đề là gì. vì vậy tôi đã suy nghĩ nếu có bất kỳ phương pháp để truy cập trực tiếp phiên để các chủ đề có thể lưu trữ trạng thái của nó ?? –

0

Tôi không chắc chắn rằng django là chủ đề an toàn. Ví dụ: django/core/urlresolvers.py không an toàn với chủ đề nếu bạn sử dụng cấu hình Apache + mod_wsgi với nhiều luồng cho mỗi quy trình. nhưng họ làm việc để làm điều đó. một số vé có trên hệ thống bán vé django 15849

2

Phiên Django là một từ điển được tìm nạp khi bắt đầu xử lý yêu cầu và được lưu lại vào cuối [source]. Do đó nếu bạn thực hiện các thay đổi song song với nó, thì một trong những thay đổi đó sẽ chiếm ưu thế. Nhưng điển hình là một người dùng con người không thể thực hiện những hành động song song như vậy và công việc kinh doanh vẫn tiếp diễn.

Bây giờ, tôi hoàn toàn không nhận được ví dụ của bạn nhưng có vẻ như bạn đang cố gắng lạm dụng từ điển phiên. Tôi đã phát triển khá một vài trang web dựa trên Django, tôi đã mắc kẹt trên một số vấn đề liên quan đến những hạn chế hoặc lỗi bên trong Django, nhưng vẫn rối tung với phiên dict từ nhiều chủ đề với tôi như một ví dụ về sách giáo khoa lạm dụng phiên này ..

Có lẽ chúng ta có thể tìm ra giải pháp khi bạn viết thêm điều gì đó về những gì bạn đang cố gắng đạt được?

0

Như đã đề cập bởi @Krumelur, các chuỗi Python sẽ không chạy cùng lúc vì khóa interpeter toàn cầu (GIL) - đó là sự thiếu hụt, không phải là một tính năng nên không dựa vào nó.

Cách khắc phục hiện tại là tạo quy trình con bằng cách sử dụng multiprocessing module. Bạn có thể kiểm tra xem một tiến trình con có đang chạy hay không bằng cách sử dụng hàm is_alive() của cá thể Process. Xem tài liệu cho số juicy details.

Các vấn đề liên quan