自己实现的文件独占锁

本文介绍了一个自定义的文件锁机制,用于防止同一应用程序内多次打开同一个文件。通过使用临界区对象来同步对文件的访问,并跟踪每个文件的锁定状态。


在Windows中,文件可以共享模式打开,也可以以独占方式打开,通过在API CreateFile 传递不同的参数实现(0,File_Share_Read,File_Share_Write)。
本文没有使用API,而是自己实现锁机制。可以避免应用程序多次打开同一个文件。代码如下:

//head File

class CFileLocker
{
public:
	CFileLocker(const string& sFilePath);
	CFileLocker(const char* szFilePath);
	~CFileLocker();
private:
	static void LockFile(const string& sFileName);
	static void UnLockFile(const string& sFileName);
	string m_sFile;
};


//Source File

static map<string, CCriticalSection> g_FileLocks;
static map<string, int> g_LockCount;
static CCriticalSection g_lockMap;

CFileLocker::CFileLocker(const string& sFilePath)
{
	if (!sFilePath.empty())
	{
		LockFile(sFilePath);
		m_sFile = sFilePath;
	}
}

CFileLocker::CFileLocker(const char* szFilePath)
{
	if (NULL != szFilePath && szFilePath[0] != '\0')
	{
		LockFile(szFilePath);
		m_sFile = szFilePath;
	}
}

CFileLocker::~CFileLocker()
{
	if (!m_sFile.empty())
	{
		UnLockFile(m_sFile);
	}
}


void CFileLocker::LockFile(const string& sFileName)
{
	CCriticalSection* pMutex = NULL;
	{
		g_lockMap.Lock();
		//create object
		if (g_FileLocks.count(sFileName) == 0)
		{
			pMutex = new CCriticalSection;
			g_FileLocks[sFileName] = pMutex;
			g_LockCount[sFileName] = 0;
		}
		else
		{
			pMutex = g_FileLocks[sFileName]; 
		}
		g_LockCount[sFileName]++;
		g_lockMap.UnLock();
	}
	if (NULL != pMutex)
	{
		pMutex->Lock();
	}
}

void CFileLocker::UnLockFile(const string& sFileName)
{
	g_lockMap.Lock();
	g_FileLocks[sFileName]->Unlock();
	if (g_LockCount[sFileName] == 1)
	{
		g_LockCount.erase(sFileName);
		delete g_FileLocks[sFileName];
		g_FileLocks.erase(sFileName);
	}
	else
	{
		g_LockCount[sFileName]--;
	}
	g_lockMap.UnLock();
}


文件独占锁(Exclusive Lock)是一种文件的方式,它可以防止其他进程对同一文件进行修改或删除,从而保证数据的完整性和一致性。在 Linux 系统中,文件独占锁可以通过 fcntl 函数实现。 下面是一个简单的示例程序,演示了如何在 Linux 系统中使用 fcntl 函数实现文件独占锁: ```c #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; struct flock fl; // 打开文件 fd = open("test.txt", O_RDWR); if (fd == -1) { perror("open"); return -1; } // 设置文件属性 fl.l_type = F_WRLCK; // 独占锁 fl.l_whence = SEEK_SET; // 文件起始位置 fl.l_start = 0; // 定起始位置 fl.l_len = 0; // 定长度(0 表示整个文件) fl.l_pid = getpid(); // 进程 ID // 获取文件 if (fcntl(fd, F_SETLK, &fl) == -1) { perror("fcntl"); return -1; } // 输出文件内容 char buf[1024]; ssize_t len; while ((len = read(fd, buf, sizeof(buf))) > 0) { write(1, buf, len); } // 释放文件 fl.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fl) == -1) { perror("fcntl"); return -1; } // 关闭文件 if (close(fd) == -1) { perror("close"); return -1; } return 0; } ``` 在上面的示例程序中,我们首先通过 open 函数打开了一个名为 test.txt 的文件,并设置了文件的读写权限。接着,我们定义了一个 struct flock 结构体,用于设置文件的属性。其中,l_type 属性设置为 F_WRLCK 表示独占锁,l_whence 属性设置为 SEEK_SET 表示从文件起始位置开始定,l_start 属性设置为 0 表示从文件起始位置开始定,l_len 属性设置为 0 表示定整个文件,l_pid 属性设置为 getpid() 表示获取当前进程的 ID。 接着,我们通过 fcntl 函数获取文件。如果获取成功,就可以读取文件内容了。最后,我们释放了文件,并关闭了文件。 需要注意的是,在使用文件独占锁时,我们需要遵循一些规则,以免出现死等问题。例如,如果多个进程都要对同一文件进行独占锁定,那么它们必须按照相同的顺序获取,否则可能会出现死。此外,如果一个进程已经获取了文件,那么它需要在使用完文件后释放,否则其他进程将无法访问该文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值