检查是否使用std :: fstream编写文件

Checking whether a file is being written to with std::fstream

本文关键字:fstream 文件 std 是否 检查      更新时间:2023-10-16

我正在使用 std::fstream写下一个名为" results.dat"的文件。这是不同步的,在完全不同的C 程序中运行的"读取"answers"写入"函数。我想在写信之前检查该文件当前尚未读取。

假设我的数据是10个浮子的数组,然后我的"写入"功能看起来像:

std::ofstream file_out("results.dat", std::ios::binary | std::ios::trunc);
file_out.write((char*)&data, 10 * sizeof(float));
file_out.close();

和我的"读取"功能看起来像:

std::ifstream file_in("results.dat", std::ios::binary);
file_in.read((char*)&data, 10 * sizeof(float));
file_in.close();

如果当前正在读取文件" results.dat",则我想在循环中等待我的"写"功能等待,直到不再读取它为止。我该如何实现?

使用Windows上的LockFile()函数或flock()用于Linux/unix。

对于同步案例 std::ios::tie

tie()用于确保在从流到流到的输入之前出现绑带流的输出它被绑在一起。例如,coutcin绑定:

cout << "Please enter a number: ";
int num;
cin >> num;

此代码未明确调用cout.flush(),因此cout没有绑定到cin,用户会看到输入请求。

这是另一个示例:

#include <iostream>     // std::ostream, std::cout, std::cin
#include <fstream>      // std::ofstream
int main () {
std::ostream *prevstr;
std::ofstream ofs;
ofs.open ("test.txt");
std::cout << "tie example:n";
*std::cin.tie() << "This is inserted into cout";
prevstr = std::cin.tie (&ofs);
*std::cin.tie() << "This is inserted into the file";
std::cin.tie (prevstr);
ofs.close();
return 0;
}

在这里进一步阅读。

对于使用 flock()的异步案例:

示例:

锁定文件的创建必须是原子。标准前<fstream.h>库过去曾具有保证原子文件创建的ios::noshare标志。可悲的是,它已从库中删除,该图书馆取代了<fstream.h>。结果,我们被迫使用<fcntl.h>(在UNIX和Linux下)或<io.h>(Windows)中声明的传统UNIX文件I/O接口来确保原子操作。

进程可以写入数据文件之前,它应该获得这样的锁:

#include <fcntl.h> // for open()
#include <cerrno> // for errno 
#include <cstdio> // for perror()
int fd;
fd=open("password.lck", O_WRONLY | O_CREAT | O_EXCL)

如果open()呼叫成功,它将返回一个描述符,这是一个小的正整数,可以标识该文件。否则,它将返回-1并将匹配的错误代码分配给全局变量errnoO_CREAT标志指示如果不存在文件,则open()应该创建它。O_EXCL标志确保呼叫为atomic;如果文件已经存在,则open()将失败并将errno设置为EEXIST。这样,您保证一次只有一个过程可以容纳锁。

您检查open()的返回代码如下:

int getlock() // returns the lock's descriptor on success
{
      if (fd<0 && errno==EEXIST){
      // the file already exist; another process is 
      // holding the lock
      cout<<"the file is currently locked; try again later";
      return -1;
      }
      else if (fd < 0){
      // perror() appends a verbal description of the current
      // errno value after the user-supplied string
      perror("locking failed for the following reason");
      return -1;
      }
      // if we got here, we own the lock
      return fd;
}

一旦一个进程拥有锁,它就可以安全地写入数据文件。完成文件后,它应如下删除锁:

remove("password.lck");目前,数据文件被视为已解锁,另一个过程可以访问它。

或使用: pthread_rwlockattr

#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include "check.h"
pthread_rwlock_t rwlock;
void *rdlockThread(void *arg)
{
int rc;
printf("Entered thread, getting read lockn");
rc = pthread_rwlock_rdlock(&rwlock);
checkResults("pthread_rwlock_rdlock()n", rc);
printf("got the rwlock read lockn");
sleep(5);
printf("unlock the read lockn");
rc = pthread_rwlock_unlock(&rwlock);
checkResults("pthread_rwlock_unlock()n", rc);
printf("Secondary thread unlockedn");
return NULL;
}
void *wrlockThread(void *arg)
{
int rc;
printf("Entered thread, getting write lockn");
rc = pthread_rwlock_wrlock(&rwlock);
checkResults("pthread_rwlock_wrlock()n", rc);
printf("Got the rwlock write lock, now unlockn");
rc = pthread_rwlock_unlock(&rwlock);
checkResults("pthread_rwlock_unlock()n", rc);
printf("Secondary thread unlockedn");
return NULL;
}
int main(int argc, char **argv)
{
int rc=0;
pthread_t thread, thread1;
printf("Enter Testcase - %sn", argv[0]);
printf("Main, initialize the read write lockn");
rc = pthread_rwlock_init(&rwlock, NULL);
checkResults("pthread_rwlock_init()n", rc);
printf("Main, grab a read lockn");
rc = pthread_rwlock_rdlock(&rwlock);
checkResults("pthread_rwlock_rdlock()n",rc);
printf("Main, grab the same read lock againn");
rc = pthread_rwlock_rdlock(&rwlock);
checkResults("pthread_rwlock_rdlock() secondn", rc);
printf("Main, create the read lock threadn");
rc = pthread_create(&thread, NULL, rdlockThread, NULL);
checkResults("pthread_createn", rc);
printf("Main - unlock the first read lockn");
rc = pthread_rwlock_unlock(&rwlock);
checkResults("pthread_rwlock_unlock()n", rc);
printf("Main, create the write lock threadn");
rc = pthread_create(&thread1, NULL, wrlockThread, NULL);
checkResults("pthread_createn", rc);
sleep(5);
printf("Main - unlock the second read lockn");
rc = pthread_rwlock_unlock(&rwlock);
checkResults("pthread_rwlock_unlock()n", rc);
printf("Main, wait for the threadsn");
rc = pthread_join(thread, NULL);
checkResults("pthread_joinn", rc);
rc = pthread_join(thread1, NULL);
checkResults("pthread_joinn", rc);
rc = pthread_rwlock_destroy(&rwlock);
checkResults("pthread_rwlock_destroy()n", rc);
printf("Main completedn");
return 0;
}

这里有几个有用的资源:1、2和3。

linux/unix?使用流程共享的pthread_rwlock。

如果两个进程都在同一台计算机上运行,则可以使用概要互联克。一次只允许一个过程与数据文件(资源)进行交互。

所有OSS上都有不同的操作通信,但是Boost库为所有通用系统提供了一个统一的接口。

代码看起来像这样:

作家:

#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
using namespace boost::interprocess;
named_mutex mutex(open_or_create, "data_file_access_mutex");
void write_function() {
    scoped_lock<named_mutex> lock(mutex);
    std::ofstream file_out("results.dat", std::ios::binary | std::ios::trunc);
    file_out.write((char*)&data, 10 * sizeof(float));
    file_out.close();
}

阅读器:

#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
using namespace boost::interprocess;
named_mutex mutex(open_or_create, "data_file_access_mutex");
void read_function() {
    scoped_lock<named_mutex> lock(mutex);
    std::ifstream file_in("results.dat", std::ios::binary);
    file_in.read((char*)&data, 10 * sizeof(float));
    file_in.close();
}