多线程读写同个文件会不会有访问冲突或者异常?我们写个程序来测试一下
/*** Created by fangruibin* 测试多线程读写文件*/#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>const char* fileName = "test.txt";void processRead()
{FILE* fp = fopen(fileName, "r");if (fp == NULL){printf("open file for read failed\n");return;}// 获取文件长度long startPos = ftell(fp);fseek(fp, 0, SEEK_END);long endPos = ftell(fp);long fileSize = endPos - startPos;fseek(fp, 0, SEEK_SET);char* pBuf = (char*)malloc(fileSize + 1);size_t readSize = fread(pBuf, 1, fileSize, fp);if ((long)readSize != fileSize){printf("read not complete %ld\n", (long)readSize);}pBuf[fileSize] = '\0';if (strlen(pBuf) == 0){printf("read empty\n");}printf("read:\n%s\n", pBuf);free(pBuf);fclose(fp);
}void processWrite()
{FILE* fp = fopen(fileName, "w");if (fp == NULL){printf("open file for write failed\n");return;}const char* pData = "2222222222222222222222222222\n2222222222222222222222222222\n2222222222222222222222222222\n";size_t dataLen = strlen(pData);size_t writeLen = fwrite(pData, 1, dataLen, fp);if (dataLen != writeLen){printf("write not complete %ld\n", (long)writeLen);}fclose(fp);
}void processReadWrite(const char* pData)
{FILE* fp = fopen(fileName, "w+");if (fp == NULL){printf("open file for read&write failed\n");return;}size_t dataLen = strlen(pData);size_t writeLen = fwrite(pData, 1, dataLen, fp);if (dataLen != writeLen){printf("write not complete %ld\n", (long)writeLen);}// 获取文件长度fseek(fp, 0, SEEK_SET);long startPos = ftell(fp);fseek(fp, 0, SEEK_END);long endPos = ftell(fp);long fileSize = endPos - startPos;fseek(fp, 0, SEEK_SET);char* pBuf = (char*)malloc(fileSize + 1);size_t readSize = fread(pBuf, 1, fileSize, fp);if ((long)readSize != fileSize){printf("read not complete %ld\n", (long)readSize);}pBuf[fileSize] = '\0';printf("[rw] read:\n%s\n", pBuf);free(pBuf);fclose(fp);
}//线程1
void* threadFunc1(void* p)
{while (1){// const char* pData = "111111111111111111111111111\n111111111111111111111111111\n";// processReadWrite(pData);processRead();usleep(100 * 1000);}return NULL;
}//线程2
void* threadFunc2(void* p)
{while (1){// const char* pData = "222222222222222222222222222\n222222222222222222222222222\n";// processReadWrite(pData);processWrite();usleep(100 * 1000);}return NULL;
}int main()
{//初始化线程pthread_t hThread1;pthread_t hThread2;if (pthread_create(&hThread1, NULL, &threadFunc1, NULL) != 0){printf("create thread 1 failed\n");return -1;}if (pthread_create(&hThread2, NULL, &threadFunc2, NULL) != 0){printf("create thread 2 failed\n");return -1;}while (1){sleep(1);}return 0;
}
代码中我们设计了两个线程,第一个线程从test.txt文件中读内容,第二个线程不断地向test.txt文件写入内容,然后我们看看读出来的内容和我们写入的内容是不是一样的
运行结果:
fang@fang-deepin:~/dev/chrifang/test/cpp/file$ ./multi_thread
read:
2222222222222222222222222222
2222222222222222222222222222
2222222222222222222222222222read not complete 0
read empty
read:read not complete 0
read empty
read:read not complete 0
read empty
read:read empty
read:read not complete 0
read empty
read:read not complete 0
read empty
read:read empty
read:read:
2222222222222222222222222222
2222222222222222222222222222
2222222222222222222222222222
可以看到有很多读取结果为空的,证明多线程读写文件是会有访问冲突的。如何避免冲突呢?
1) 同个进程内读写文件加上线程锁
2) 不同进程读写文件使用flock()函数去加锁