C++ - låsfil (lock file)

Kategori overført fra Linux1

C++ - låsfil (lock file)

Innleggav TO » lør 10.10.2009 17:53

Jeg lurer på om det er noen standard måte for "lock file" i C++?

Anvendelse: Mange applikasjoner kan lese fra en datafil samtidig, men når det skrives til datafilen så har skriveren ekslusiv adgang. For å styre dette tenkes låsfil(er) anvendt.

For C har jeg sett på "fcntl", "flock" samt "lock" (ikke sjekket denne så godt enda).
Disse gjør jobben men jeg klarer ikke å konvertere det til C++ siden jeg ikke ser at C++ bruker "file descriptor". Eksempelkode vill vært glitrende.
medlem i 212 måneder
 

Re: C++ - låsfil (lock file)

Innleggav ak » lør 10.10.2009 19:21

Du sender litt blandede signaler om hva du ønsker å få til. Låsefiler er egentlig mest aktuelle for å beskytte flere filer mens de ikke er i bruk, f.eks. et helt directory der bare en og en fil er åpen av gangen. For hvis du bare har en fil, så kan du like godt behandle den slik du ville behandlet låsefilen.

Se om denne artikkelen hjelper:
http://www.informit.com/guides/content. ... seqNum=144

Administrator
Brukerens avatar
medlem i 236 måneder
 

Re: C++ - låsfil (lock file)

Innleggav TO » søn 11.10.2009 2:42

Takk for tipset. Så lenge jeg får et filnummer (file descriptor) på fila, så kan låsen settes. Samme prosess kan deretter åpne fila flere ganger, på passende måte. Her er eksempelkoden (C++) som jeg har snekret sammen. Kanskje ikke så elegant, men korreksjon og tips er flott :-) .

Kode: Merk alt
/*
  This program creates and locks ./example.lock, waiting for the user
  before unlocking the file again.

  Compilation: g++ ./code.cpp  -o programname
 
  By running this program in many terminals simultanously, file
  locking can be demonstrated.

  1 $  ./programname  read
  2 $  ./programname  write first
  3 $  ./programname  write second
  4 $  ./programname  read 

 
  References:
  http://linux.die.net/man/2/flock
  http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=144
  http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html

  http://www.oracle.com/technology/documentation/berkeley-db/xml/api_reference/CXX/frame_main.html
  (The Db::fd() method provides access to a file descriptor representative of the underlying database.
  A file descriptor referring to the same file will be returned to all processes that call Db::open()
  with the same file parameter.
  This file descriptor may be safely used as a parameter to the fcntl(2) and flock(2) locking functions.
  */
 
#include <iostream>   // for std::cin, std::cout std::cerr
#include <string>     // standard C++ string
#include <fstream>    // file I/O, ex: ifstream, ofstream
using namespace std;  //  to write XYZ instead of std:XYZ, ex: cout

#include <sys/file.h> // for flock(2)
#define FILENAME "example.lock"

int main(int argc,char **argv)
{
  for(int i = 0; i<argc && 1==0; i++)
    {
      if (i==0) cout << "argc = " << argc << endl;
      cout << "argv[" << i << "] = " << argv[i] << endl;
    }
 
  string programname=string(argv[0]);
  if (argc<2)
    {
      cerr<<"Purpose -- demonstrate file locking"<<endl;
      cerr<<"./"<<programname << " read"<<endl;
      cerr<<"./"<<programname << " write something"<<endl;
      exit(1);
    }
   
    string locktype=string(argv[1]);
    string label="";
    if ( locktype=="read")
      {
   label="not used";
      }
    else if (locktype=="write")
      {
   if (argc<3)
     {
       cerr<<"./"<<programname << " write something"<<endl;
       exit(1);
     }
   label=string(argv[2]);
      }
    else
      {
   cerr<<"error: unsupported locktype: "<<locktype<<endl;
   exit(1);
      }
   
    string lockfile=FILENAME; // name of lockfile
    int fd;                   // associated file descriptor
    fd=open(lockfile.c_str(),O_RDWR|O_CREAT, 0644);
    if (fd==-1)
      {
   cerr<<"error: could not open file: "<< lockfile<<endl;
   exit(1);
      }
   
    // lock the file
    if (locktype=="write")
      {
   cerr<<"./"<< lockfile << " ("<<fd<<"): ";
   cerr<<"waiting for an exclusive write lock ... ";
   if (flock(fd,LOCK_EX) != 0)
     {
       cerr<<endl<<"error: flock(fd,LOCK_EX):"<<endl;
       exit(1);
     }
   cerr<<" got it!"<<endl;
   
   // append the text label to the lock file
   ofstream outfile;
   outfile.open(lockfile.c_str(), ios::app);
   if (!outfile)
     {
       cerr<<"error: <ofstream>: unable to open file: ./"<<lockfile<<endl;
       exit(1);
     }
   outfile<<label<<endl;
   outfile.close();
      }
    else if (locktype=="read")
      {
   cerr<<"./"<< lockfile <<" ("<<fd<<"): ";
   cerr<<"waiting for a shared read lock ... ";
   if (flock(fd,LOCK_SH) != 0)
     {
       cerr<<endl<<"error: flock(fd,LOCK_SH): "<<endl;
       exit(1);
     }
   cerr<<" got it!"<<endl;
   
   // read the content of the lock file using C++ ifstream
   ifstream infile;
   infile.open(lockfile.c_str());
   if (!infile)
     {
       cerr<<"error: <ifstream>: unable to open file: ./"<< lockfile<<endl;
       exit(1);
     }
   string line;
   int i=0;
   while (getline(infile,line))
     {
       cout<<"./"<<lockfile<<", "<<++i<<": " << line<<endl;
     }
   infile.close();
      }
   
    string a;
    cerr<<"To cancel the lock, press any character followed by enter: ";
    cin>>a;
   
    // close the lockfile
    if (close(fd)==-1)
      {
   cerr<<"error: something went wrong when closing the lock file"<<endl;
      }
    exit(0);
}
medlem i 212 måneder
 


Returner til Utvikling i Linux



Hvem er i Forumene

Registrerte brukere: Google [Bot]