[英]File locking between C++ and PHP
我正在創建一種有點愚蠢但有效的方法來在PHP中創建作業,然后C ++開始使用。 PHP創建的作業文件是簡單的文本文件,C ++逐行讀取該文件,並將每一行添加到向量中。
資料夾:
問題:PHP假定文件不在“作業保持”中,但C ++並未處理該文件,但C ++實際上僅將其移至該位置以防止作業執行兩次(如下所示)。 C ++仍然需要讀取文件以將其內容放入向量中,因此在發生這種情況時,我需要防止PHP訪問此文件。
另外,我需要禁止C ++在PHP編輯“ jobhold”文件夾中的作業文件時對其進行處理。
C ++函數,用於檢查自上次完成此工作以來是否經過了足夠的時間 :
-> 如果PHP對該文件具有鎖定,則需要取消這兩個步驟(3和4) 。 這意味着文件將被完全忽略,直到PHP完成它為止。
處理“ jobs”文件夾中文件的C ++函數:
-> 我需要確保PHP仍無法處理該文件,即使該文件位於“ jobhold”中也是如此 。 C ++需要立即鎖定它(之后,期間, 之前? ),因此PHP絕不可能拾取該文件,並且直到線程內的某個地方才釋放它。
處理作業文件的C ++線程:
-> 在此步驟之后,可以釋放文件鎖定 ,這時PHP可以鎖定文件,因此C ++將不再處理該文件。
PHP (當前僅檢查“ jobhold”中的文件是否存在 ):
<?php
if(isset($_GET['edit']))
{
$filename = $startdir.'jobhold/'.$_GET['edit'];
while (!file_exists($filename))
{
while(file_exists($startdir.'jobs/'.$_GET['edit']))
{
//Wait until C++ moves the file from "jobs" to "jobhold" by doing nothing
}
if(file_exists(filename)
{
break 1; //The file exists now, we may break the while.
}
//If we reached this point, the job simply doesn't exist.. so die.
echo "The job $_GET[edit] doesn't exist. <br /><br />";
die();
}
}
/* Other code here, such as HTML form so user can edit the txt file */
?>
->需要在PHP中添加另一項檢查,以檢查C ++是否在“ jobhold”中的作業文件上鎖定了鎖定。 如果是,請等到鎖定被刪除后再立即鎖定文件,以使C ++無法再處理該文件。 像這樣(愚蠢的例子):
<?php
while(file_locked_by_c++($startdir.'jobshold/'.$_GET['edit']))
{
//Wait until C++ releases the file by doing nothing
}
/* Lock file NOW */
?>
我確實找到了這個線程 ,盡管我不介意在C ++代碼中使用C,但是如果沒有適當的例子,我也沒有設法弄清楚如何將這些問題應用於我的情況。
PS :之所以沒有發布任何實際的C ++代碼,是因為我對C ++的使用(有時是凌亂但大多是多余的)方式感到惱火,因為我是C ++的新手,這只會使其他新手和/或混淆擺脫我在這里想要實現的目標。
如果您堅持要看一些代碼,那很好,但是請不要提及混亂/冗余,因為我已經知道了 ,它們只是便宜的解決方法,我將在以后的階段中進行“修復”。 如果您是新手,請確保不要復制這些錯誤。
抱歉,這么長的篇幅太簡單了,但我需要100%正確,否則整個應用程序可能會崩潰。
更新:
我目前正在這樣做:
添加了一個名為“ lock”的新文件夾,其中將包含php-jobnameX.txt
和c-jobnameX.txt
,其中jobnameX是當前作業的名稱。
C ++:
- 當C ++檢查自上次以來是否經過了足夠的時間時,我們在“ jobhold”中執行了jobfile,在將文件從“ jobhold”移至“ jobs”之前,它首先檢查php是否已在“ lock”中創建了文件。 如果是這樣,我們將跳過文件。
//This function will check if PHP has created a lock-file
bool checkifphplock(char* filename)
{
ifstream fin(filename);
if (fin)
{
fin.close();
return true;
}
return false;
}
int cont = 1;
if(checkifphplock(phplockfile))
{
cont = 0; //php lock found, so we go byebye
}
if(cont == 1)
{
/* Keep doing stuff */
}
- 當php開始在“作業”中的作業文件上工作時,在將作業文件從“作業”移回“作業持有”之前,它將在“鎖”中創建一個鎖定文件以通知php它仍在處理該文件。
ofstream myfileclock;
myfileclock.open (clockfile, fstream::in | fstream::out | fstream::app);
myfileclock << " ";
myfileclock.close();
- 一旦c ++線程完成了將文件內容復制到向量中,鎖定文件將被刪除以通知PHP它准備好再次進行編輯。
system("rm /path/to/program/lock/c-jobnameX.txt");
PHP:
- 編輯后,通過在“ lock”中創建文件來立即獲得鎖定。
//Obtain lock immediately:
$file = $startdir."lock/php-$_GET[edit]";
if(!is_file($file)){ file_put_contents_atomic($file," "); chmod($file,0777);} //Make file if there is none
if(!is_writable($file)){chmod($file.'/',0777);} //Chmod file if not writable
if(!is_writable($file)){die("File \"$file\" not writable.");} //Die if not writable
- 獲取鎖定后,再次檢查c ++是否也沒有鎖定文件(以防C ++和PHP都在同一時間請求了作業文件)
while (file_exists($startdir."lock/c-$_GET[edit]"))
{
//Do nothing while c/c++ has a lock
}
- 如果c ++已將文件從“ jobhold”移到“ jobs”,我們將等到文件移回。
//Wait for filename to exist in jobhold. Or die if it doesn't exist in any folder.
$filename = $startdir.'jobhold/'.$_GET['edit'];
while (!file_exists($filename))
{
while(file_exists($startdir.'jobs/'.$_GET['edit']))
{
//Wait until C++ moves the file from "jobs" to "jobhold" by doing nothing
}
if(file_exists($filename))
{
break 1; //The file exists now, we may break the while.
}
//If we reached this point, the job simply doesn't exist.. so die.
echo "The job $_GET[edit] doesn't exist. <br /><br />";
unlink($file); //Remove lock for this non-existing job
die();
}
/* Continue creating form to edit the file etc. */
從技術上講,最后一步永遠是不可能的,因為如果C / C ++沒有鎖,則文件不能(不應該)處於“作業”中,但是檢查不會受到損害。
這樣是否可以100%確保PHP和C / C ++不能同時處理文件?
一種非常簡單的文件鎖定方法是在文件頂部有一行,顯示讀取的鎖定內容或您喜歡的內容。 在執行任何操作之前,每段代碼都會檢查該行是否存在。 文件的第一個也是最后一個動作是通過添加“已鎖定”一詞來鎖定/解鎖文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.