如何使用flock()

3
我希望使用系统锁来避免竞争条件。一个进程是opencv程序,将捕获的图像保存为.jpeg文件。另一个进程是浏览器从服务器获取相同的图像文件。我想避免这两个进程之间的竞争条件。我是否正确地使用了flock函数?
我的opencv代码如下:
#include<sys/file.h> 
#include<fcntl.h>
#include<string.h>
#include "cv.h"
#include "highgui.h"
#include <stdio.h>

int main() 
{
    int fd1,fd2;
    struct flock lock;
    fd1=open("a1.jpg",O_WRONLY);
    fd2=open("a2.jpg",O_WRONLY);
     lock.l_type=F_UNLCK;
     fcntl(fd1,F_SETLKW,&lock);

    CvCapture* capture = cvCaptureFromCAM(-1);
    if ( !capture )
    {

            fprintf( stderr, "ERROR: capture is NULL \n" );
            getchar();
            return -1;
    }

    cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
    while ( 1 )
    {
            IplImage* frame = cvQueryFrame( capture );
            if ( !frame )

                    fprintf( stderr, "ERROR: frame is null...\n" );
                    getchar();
                    break;
            }
            cvShowImage( "mywindow", frame );
            if(flock(fd1,LOCK_EX)==0)
            {
            printf("A1 is locked");
            cvSaveImage("a1.jpg",frame,0);
            flock(fd1,LOCK_UN);
            printf("A1 unlocked");
            }
            else
            {
            flock(fd2,LOCK_EX);
            cvSaveImage("a2.jpg",frame,0);
            flock(fd2,LOCK_UN);
            printf("A2 is unlocked");
            }
            if ( (cvWaitKey(500) & 255) == 27 )
                    break;
    }
    cvReleaseCapture( &capture );
    cvDestroyWindow( "mywindow" );
    close(fd1);
    close(fd2);
    return 0;

}

我的 .php 文件是

<?php
$dest='a.jpg'; 
$src1='a1.jpg';
$src2='a2.jpg';
if(flock($fp1,LOCK_EX))
{
    echo "a1";
    $img=imagecreatefromjpeg($src1);
    $copy=imagejpeg($img,$dest);
    imagedestroy($img);
    flock($fp1,LOCK_UN);
}
else
{
    echo "A2";
    flock($fp2,LOCK_EX);
    $img=imagecreatefromjpeg($src2);
    $copy=imagejpeg($img,$dest);
    imagedestroy($img);

    flock($fp2,LOCK_UN);
}
?>

这个PHP文件是由客户端使用AJAX调用的。


你对使用的正确性有什么不确定之处?你测试过代码并且得到了奇怪的结果吗?能详细说明一下吗? - hakre
如果flock成功,它应该返回0,但是它没有返回任何值。而且当我尝试通过其他进程访问文件时,我可以访问它。这意味着我没有在那个文件上获得锁定。 - user927774
在C部分还是PHP部分?http://php.net/flock - hakre
你知道使用flock创建的锁是“建议性”锁吗?除非另一个进程也尝试锁定该文件,否则锁不会阻止其他进程。 - John
另外,如果它不返回0,它会返回什么?flock的返回类型是int,因此它将始终返回一个整数。 - John
@user927774,你的代码没有检查flock的所有返回值。你怎么知道它没有返回任何值?你还在那里调用了fcntl,fcntl锁和flock锁之间没有互动。 - nos
1个回答

0

flock(2)会在请求独占锁并且锁不可用时阻塞。它会在一切正常时返回0,如果有错误则返回-1,您可以通过perror(3)或errno变量进行检查。

看起来您的C代码至少模糊地遵循了正确的协议 - 在写入共享文件之前获取独占锁,然后解锁 - 但我无法理解您的代码尝试的是什么,因此很难理解您的代码是否做得正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接