锁定同时在文件中写入日志的多个进程的可能性
possibilty of locking for multi processes writing their log in a file concurrently
我发现了一些在多进程环境中使用 fputs 和 fflush 的错误。
所以我编写了如下简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "windows.h"
#define FILENAME "test.txt"
int main(int argc , char *argv[])
{
FILE *file;
file = fopen(FILENAME , "a");
char buf[10240 + 100];
int pid = GetCurrentProcessId();
char buf_pid[20];
itoa(pid, buf_pid, 10);
int ii = 0;
while(ii < 10000)
{
time_t now = time(0);
struct tm tstruct;
char tt[80];
tstruct = *localtime(&now);
strftime(tt, sizeof(tt), "%Y/%m/%d %X", &tstruct);
strcpy(buf, tt);
strcpy(buf + strlen(tt), " ");
strcpy(buf + strlen(tt) + 1, buf_pid);
strcpy(buf + strlen(tt) + strlen(buf_pid), " ");
int len = strlen(tt) + strlen(buf_pid) + 1;
int a = rand()%10240;
char temp;
for(int i=0;i<a;i++)
{
temp = 'a' + rand()%25;
memset(buf + len, temp, 1);
len++;
}
buf[len++] = '\n';
buf[len++] = 0;
//Sleep(1);
printf("%d %s %d %d\n", ii, tt, pid, a);
fputs(buf, file);
fflush(file);**
ii++;
}
然后我运行了一些批处理文件,如下所示:
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
当然,结果如下所示。
2019/11/08 22:57:14 261 rjatydimofugclqurclqecdrhvqsuwbvntmryktdl..
2019/11/08 22:57:14 261 ixoqldswtmhmjxqedqkprngproxvfpeuagbsxexje..
2019/11/08 22:57:14 261 skrhmutgpnkpwopudobptikjrfogdeairwyglcrqe..
2019/11/08 22:57:14 261 sqytmhtrnqkrtnfigwgcvvacgklmcjxinhehaqish..
2019/11/08 22:57:14 261 pvdvsfksuonldbwstvgflwjpecfymtfdrsnxlqqod..
2019/11/08 22:57:14 261 oqatxghvkhhjyvgnlymcjapedmpdakuuphbxnuqtd..
2019/11/08 22:57:14 261 ufrjkikbwvlvjejhpnndyebmgfjbmwvldsrlephow..
..
没有明确的互斥锁,所以 fputs 和 fflush 不是自动的。
我知道 fputs 是用 os 内核中的句柄将文本写入文件缓冲区
而fflush是将buffer刷入磁盘。而且虽然没有同步对象,但是访问每个缓冲区或刷新代码的顺序将保持不变。
pos用上面的代码可以发生锁吗?
或者如果有 2 个文件正在被许多进程写入,
是pos兄弟锁吗?
我找到了相关的好文章,但我不相信它真的发生了。
Is a sync/flush needed before writes to a locked file from multiple threads/processes in fopen a+ mode?
fputs and fflush, writing and buffer process
谢谢!
程序中有一个'hidden'锁——当代码打开日志文件时,它使用APPEND模式("a"打开)。这将导致在 open
系统调用上设置标志 O_APPEND。
引用自 man open:
O_APPEND
The file is opened in append mode. Before each write(2), the file offset is positioned at
the end of the file, as if with lseek(2). The modification of the file offset and the
write operation are performed as a single atomic step.
该标志保证每个 'write' 操作(每当执行 printf 以将行刷新到文件时执行)都是原子的,并且不会与其他进程的输出混合。 同步和锁定发生在操作系统内核中,不需要用户操作。
我发现了一些在多进程环境中使用 fputs 和 fflush 的错误。 所以我编写了如下简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "windows.h"
#define FILENAME "test.txt"
int main(int argc , char *argv[])
{
FILE *file;
file = fopen(FILENAME , "a");
char buf[10240 + 100];
int pid = GetCurrentProcessId();
char buf_pid[20];
itoa(pid, buf_pid, 10);
int ii = 0;
while(ii < 10000)
{
time_t now = time(0);
struct tm tstruct;
char tt[80];
tstruct = *localtime(&now);
strftime(tt, sizeof(tt), "%Y/%m/%d %X", &tstruct);
strcpy(buf, tt);
strcpy(buf + strlen(tt), " ");
strcpy(buf + strlen(tt) + 1, buf_pid);
strcpy(buf + strlen(tt) + strlen(buf_pid), " ");
int len = strlen(tt) + strlen(buf_pid) + 1;
int a = rand()%10240;
char temp;
for(int i=0;i<a;i++)
{
temp = 'a' + rand()%25;
memset(buf + len, temp, 1);
len++;
}
buf[len++] = '\n';
buf[len++] = 0;
//Sleep(1);
printf("%d %s %d %d\n", ii, tt, pid, a);
fputs(buf, file);
fflush(file);**
ii++;
}
然后我运行了一些批处理文件,如下所示:
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
start filewrite.exe
当然,结果如下所示。
2019/11/08 22:57:14 261 rjatydimofugclqurclqecdrhvqsuwbvntmryktdl..
2019/11/08 22:57:14 261 ixoqldswtmhmjxqedqkprngproxvfpeuagbsxexje..
2019/11/08 22:57:14 261 skrhmutgpnkpwopudobptikjrfogdeairwyglcrqe..
2019/11/08 22:57:14 261 sqytmhtrnqkrtnfigwgcvvacgklmcjxinhehaqish..
2019/11/08 22:57:14 261 pvdvsfksuonldbwstvgflwjpecfymtfdrsnxlqqod..
2019/11/08 22:57:14 261 oqatxghvkhhjyvgnlymcjapedmpdakuuphbxnuqtd..
2019/11/08 22:57:14 261 ufrjkikbwvlvjejhpnndyebmgfjbmwvldsrlephow..
..
没有明确的互斥锁,所以 fputs 和 fflush 不是自动的。 我知道 fputs 是用 os 内核中的句柄将文本写入文件缓冲区 而fflush是将buffer刷入磁盘。而且虽然没有同步对象,但是访问每个缓冲区或刷新代码的顺序将保持不变。
pos用上面的代码可以发生锁吗? 或者如果有 2 个文件正在被许多进程写入, 是pos兄弟锁吗?
我找到了相关的好文章,但我不相信它真的发生了。 Is a sync/flush needed before writes to a locked file from multiple threads/processes in fopen a+ mode? fputs and fflush, writing and buffer process
谢谢!
程序中有一个'hidden'锁——当代码打开日志文件时,它使用APPEND模式("a"打开)。这将导致在 open
系统调用上设置标志 O_APPEND。
引用自 man open:
O_APPEND The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.
该标志保证每个 'write' 操作(每当执行 printf 以将行刷新到文件时执行)都是原子的,并且不会与其他进程的输出混合。 同步和锁定发生在操作系统内核中,不需要用户操作。