標籤:err block write 成功 檔案讀寫 hand 程式 失敗 情況
同意檔案操作同意檔案的問題在於邏輯有些地方不合適,如果多個線程同時寫入,在不加鎖的情況下,可能導致得到結果不如意,為了安全,和髒讀(資料庫的詞),應該使用獨佔鎖定,這就意味著每次只能被一個線程操作。其他線程只能等待,如果逾時則會報錯。
1 關鍵函數:2 fopen() // 開啟檔案或一個http地址,形成一個檔案流3 flock() // 對檔案加鎖及解鎖4 fwrite() // 對檔案讀寫操作5 fclose() // 關閉檔案流
1 fopen() resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] ) 2 3 檔案開啟模式: 4 ‘r‘ 唯讀方式開啟,將檔案指標指向檔案頭。 5 ‘r+‘ 讀寫方式開啟,將檔案指標指向檔案頭。 6 ‘w‘ 寫入方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。 7 ‘w+‘ 讀寫方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。 8 ‘a‘ 寫入方式開啟,將檔案指標指向檔案末尾。如果檔案不存在則嘗試建立之。 9 ‘a+‘ 讀寫方式開啟,將檔案指標指向檔案末尾。如果檔案不存在則嘗試建立之。 10 ‘x‘ 建立並以寫入方式開啟,將檔案指標指向檔案頭。如果檔案已存在,則 fopen() 調用失敗並返回 FALSE,並產生一條 E_WARNING 層級的錯誤資訊。如果檔案不存在則嘗試建立之。這和給 底層的 open(2) 系統調用指定 O_EXCL|O_CREAT 標記是等價的。 11 ‘x+‘ 建立並以讀寫方式開啟,其他的行為和 ‘x‘ 一樣。
1 flock() bool flock ( resource $handle , int $operation [, int &$wouldblock ] ) 2 3 4 handle 5 檔案系統指標,是典型地由 fopen() 建立的 resource(資源)。 6 operation 7 operation 可以是以下值之一: 8 ? LOCK_SH取得共用鎖定定(讀取的程式)。 9 ? LOCK_EX 取得獨佔鎖定(寫入的程式。 10 ? LOCK_UN 釋放鎖定(無論共用或獨佔)。 11 12 13 如果不希望 flock() 在鎖定時堵塞,則是 LOCK_NB(Windows 上還不支援),即遇到有鎖不等待,直接報錯返回EWOULDBLOCK14 寫法為:$re = flock(lockfd,LOCK_EX|LOCK_NB)15 有錯則返回$re = -1,errno = EWOULDBLOCK
1 fwrite() int fwrite ( resource $handle , string $string [, int $length ] ) 2 3 handle 4 檔案系統指標,是典型地由 fopen() 建立的 resource(資源)。 5 string 6 The string that is to be written. 7 length 8 如果指定了 length,當寫入了 length 個位元組或者寫完了 string 以後,寫入就會停止,視乎先碰到哪種情況。 9 10 注意如果給出了 length 參數,則 magic_quotes_runtime 配置選項將被忽略,而 string 中的斜線將不會被抽去。11 12 fwrite() 返回寫入的字元數,出現錯誤時則返回 FALSE 。
1 fclose() bool fclose ( resource $handle )2 3 handle4 檔案指標必須有效,並且是通過 fopen() 或 fsockopen() 成功開啟的。
通常這樣子並不能從根本解決阻塞問題,只能是緩解一下,最好是通過中介軟體或者reids把請求排成一個隊列,保證請求隊列不會資料丟失,但是對於寫入的資料不是那麼重要的,可以用這個方法,直接寫入,丟失就丟失了。
在前期調試的時候,可以先用這個方法直接把資料寫在檔案裡,可視化強烈一些,後期可以用mongodb替換檔案寫入,或者多個檔案分類分目錄寫入,而控制阻塞問題需要使用redis等來控制確保單檔案操作的同時,請求不會丟失。
php多線程操作同一檔案-待續