写了一个简单的 demo 来测试单文件的并发写入,给每个位置写且仅写一次不同的数字,我觉得这个场景貌似是不包含冲突的问题的,因为访问的文件地址都不一样的。但是实际结果确实是产生冲突了。希望有大佬有时间进行指教,谢谢!
代码如下
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <stdint.h>
using namespace std;
FILE *fp;
void * running(void * args){
    uint8_t* pos = (uint8_t *)args;
    FILE * nowfp = fp;
    fseek(nowfp,*pos,SEEK_SET);
    fwrite(pos,1,1,nowfp);
    delete pos;
    return 0;
}
int main(int,char **){
    fp = fopen("test.bin","wb+");
    pthread_t t_a;
    for(int i =0;i<100;i++){
        uint8_t* j = new uint8_t(i);
	    pthread_create(&t_a,NULL,running,j);
    }
    while (true)
    {
        sleep(1000);
    }
    return 0;
}
程序输出结果如下 除了第一个位置以外,有很多值为 0 的点。不太明白这个并发冲突产生在哪里。:
  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 	
00000000: 00 00 02 03 01 00 00 07 08 04 0A 0B 0C 0D 0E 0F    ................
00000010: 10 11 12 13 2F 15 16 17 18 19 1A 1B 00 1D 1E 1F    ..../...........
00000020: 20 21 22 23 00 25 26 40 28 00 2A 2B 2C 2D 2E 00    .!"#.%&@(.*+,-..
00000030: 30 31 32 33 34 35 36 37 00 39 3A 3B 00 3D 3E 3F    01234567.9:;.=>?
00000040: 00 41 42 43 44 45 46 47 3C 48 00 4B 4C 4D 4E 4F    .ABCDEFG<H.KLMNO
00000050: 50 51 52 53 54 55 56 57 58 59 00 5B 5C 5D 5E 5F    PQRSTUVWXY.[\]^_
00000060: 60 61 62 63                                        `abc
|      1ho121      2020-10-11 18:42:24 +08:00 via Android fwrite 执行之前被其它线程 fseek 改掉了位置 | 
|      2qianlv7      2020-10-11 18:44:12 +08:00 用 pwrite,FILE* 共享了位移 | 
|      3qianlv7      2020-10-11 18:45:13 +08:00 文件偏移共享了,导致冲突 | 
|  |      5geelaw      2020-10-11 18:58:19 +08:00  1 @1YsX1 #4 这是双重理解错误。 1. FILE * 实际起效果的是“被指向的” FILE 结构,而不是 FILE * 本身,复制指针的值并不会复制 FILE 结构,因此操作的是同一个 FILE 。 2. fseek 传入的参数是 FILE * 而不是 FILE *&,并不存在“操作传入的变量”这种说法,它获得的永远是传入值的副本。把 fp 复制到 nowfp 再传入是多此一举,不会有任何效果。 | 
|  |      69LCRwvU14033RHJo      2020-10-11 19:04:07 +08:00 FILE 里面有文件描述符。文件描述符只是一个数组下标而已。数组“打开文件表”是操作系统维护的,所有进程共享的。 | 
|      9abutter      2020-10-12 08:39:09 +08:00 man 2 flock | 
|  |      10jedihy      2020-10-12 09:52:43 +08:00 哈哈,楼主是不是原来写 js 的? | 
|      11Testlinuxtous      2020-10-24 03:34:48 +08:00 via iPhone @abutter 能给一个邮箱交流一下吗? | 
|      12UFc8704I4Bv63gy2      2020-12-02 00:53:12 +08:00 via Android 加锁,这个问题在 win 上应该不存在,在 unix 系统上肯定有 |