程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP中Session引起的腳本阻塞問題解決辦法

PHP中Session引起的腳本阻塞問題解決辦法

編輯:關於PHP編程

     這個問題很多做php開發朋友應該都有遇到過,一個啟用了session_start 頁面,由於執行時間過長。導致通一個用戶訪問,另外一個很簡單的啟用session_start頁面一直阻塞著。 直到第一個頁面執行完了。第二個頁面才可以讀取。這個就是,我們常說的session阻塞機制。

      解決session阻塞問題的辦法:在session操作完成後調用session_write_close()即可避免此問題;     案例一:   使用session過程中,在開啟session後,同一浏覽器,執行同一程序,不同頁面會被鎖。不同浏覽器不會出現這種情況。     疑問:是不是session_start導致了阻塞?      於是,我寫了幾個頁面測試了一下,發現是session導致了阻塞,而其他兩種情況不會造成阻塞。      查了下PHP的Bug列表,發現有人提出了這個問題:    代碼如下:Description: ------------ Calling session_start() appears to wait until other scripts have exited   that are using the same session. My guess is the 1st request locks the  session file for exclusive use, and the second request blocks until it  can open it.         PHP官方的回復是:    代碼如下:Thank you for taking the time to write to us, but this is not a bug.This is expected, the session file is locked to avoid corruption.       結合了PHP的Session機制,找到了阻塞的原因。由於PHP的Session信息是寫入文件的,1個客戶端占有1個session文件。因此,當 session_start被調用的時候,該文件是被鎖住的,而且是以讀寫模式鎖住的(因為程序中可能要修改session的值),這樣,第2次調用 session_start的時候就被阻塞了。       最簡解決方法:       查了PHP的手冊,發現一個session_write_close函數,作用是Write session data and end session,也就是寫session的數據,同時關閉這個session。因此,我們可以在用完session之後,調用這個函數關閉session 文件即可解除鎖定。一般,session是用來記錄用戶身份信息的,以便PHP進行身份認證,因此完全可以將session的讀寫放在頁面剛開始執行的時 候,在執行完以後,馬上調用session_write_close函數即可。     案例二:   上回說要改opencart其實是給opencart加一個抓取淘寶上的產品的功能,但是弄完後發現一個問題,就是當腳本在抓取的時候,因為這個過程比較慢,這個時候其他所有腳本的執行都被阻塞了,直到抓取完其他腳本才能依次執行。研究了半天沒有結果,在知乎上問了下可能是session的問題,需要調用session_write_close()來解決,那麼這個session_write_close()是干嘛用的呢,手冊上這樣寫的:    代碼如下: 結束當前session,保存session數據。   session數據通常會在腳本執行結束後被保存而並不需要調用session_write_close(),但是為保護session在任何時候都只能被一個腳本執行寫操作,session的數據會被鎖住。當同時使用框架網頁和session時你會發現,框架裡的網頁會因為這個個鎖定而逐個載入。你可以通過在所有的session數據修改保存結束後馬上結束session來加快載入時間。     這就很好的解釋了為什麼我的抓取腳本會阻塞其他頁面的原因。所以,如果你有一個需要執行時間比較長並用到session的ajax請求的話,就需要在服務器端調用session_write_close(),不然你的其他頁面就都會被掛起直到請求結束!!!  
    1. 上一頁:
    2. 下一頁: