我在PHP中创造了一种愚蠢但有效的方法来创建工作,然后C++开始工作。PHP创建的作业文件是简单的文本文件,C++逐行读取,将每一行添加到向量中。
文件夹
“作业”->新作业文件将在此处结束
“JOBHOLD”->作业文件一旦在C++上开始工作,就移到这里。
“jobstime”->保存与jobfile同名的文件,
包含纪元时间以便我可以检查自上次以来经过的时间
我们做了这项工作。
问题是:
PHP假设一个文件不是在C++中处理的,而是在“JOBHOLD”中,但是C++只把它移到了那里,以防止作业被执行两次(如下所示)。C++仍然需要读取文件来将内容放在向量中,所以我需要防止PHP在发生这种情况时访问该文件。
此外,我需要禁止C++处理“Job”文件夹中的作业文件,而该文件是由PHP编辑的。
C++函数检查我们上次做这项工作的时间是否已经过去了:
打开jobstime文件并确定X秒是否已经过去
上次我们做这个工作
如果经过足够的时间:
将jobfile从“jobhold”移动到“jobs”,以便下一个函数创建
执行作业的线程。
从“jobstime”中删除相应的时间文件,它将被重新创建
在线程中,在下一个函数中创建。
->如果PHP锁定了文件,我需要取消这两个步骤(3&4)。这意味着在PHP完成之前,该文件将被完全忽略。
处理“作业”文件夹中的文件的C++函数:
将作业文件从“jobs”移回“jobhold”,这样可以防止
线程被创建两次。
在“jobstime”中创建包含当前时间(EPOCH)的时间文件
创建将处理文件的新线程(只传递
新线程的文件名,以便它知道要处理哪个文件)
->我需要确保PHP还不能处理这个文件,即使它在“jobhold”中。C++需要立即锁定它(在之后、之前、之前)?因此,PHP不可能获取该文件,并且在线程内部的某个地方才能释放它。
处理作业文件的C++线程:
将读取作业文件(当前位于“jobhold”文件夹中)
输出,每一行被添加到由线程创建的向量中。
->在此步骤之后,可以释放文件锁,此时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 */
?>
我确实找到了this thread,虽然我不介意在C++代码中使用C,但没有找到一个合适的例子,我没有办法解决这个问题的答案。
PS:我没有发布任何实际的C++代码的原因是我会因为我的代码是新的而被烧毁(有时是凌乱的但大部分是冗余的),这会让其他新手感到困惑和/或从我想在这里得到的东西中解脱出来。
如果你坚持要看一些代码,那很好,但请不要提及混乱/冗余,因为我已经知道,它们只是廉价的解决方案,我将在稍后阶段“修复”。如果你是个新手,一定不要照搬这些错误。
pastebin
对于这么简单的事情,我很抱歉发了这么长的帖子,但是我需要把这个100%正确,否则整个应用程序可能会崩溃。
更新:
我现在正在做:
添加了一个名为“lock”的新文件夹,其中包含像
php-jobnameX.txt
和c-jobnameX.txt
这样的文件,其中jobnameX是当前作业的名称。C++:
-. 当C++检查是否有足够的时间过去之后,我们在“JOWHOLD”中执行作业文件,在将文件从“JOBHOLD”移动到“作业”之前,它首先检查PHP是否在“锁”中创建了一个文件。如果是的话,我们就跳过这个文件。
//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开始处理“jobs”中的jobfile时,在将jobfile从“jobs”移回“jobhold”之前,它会在“lock”中创建一个锁文件来通知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");
菲律宾比索:
-. 编辑时,通过在“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都同时要求JOB文件)
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++不能同时处理文件吗?
最佳答案
一个非常简单的文件锁定方法是在文件的顶部有一行,它可以读取锁定的文件或任何你喜欢的文件。每段代码都会在执行任何操作之前检查该行是否存在。文件上的第一个和最后一个操作是通过添加单词locked来锁定/解锁文件。
关于php - C++和PHP之间的文件锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8158126/