多线程写同一个文件, 数据内容出错

描述:

    * 1. 采用C语言, 多线程 对同一个文件进行写操作;
    * 2.每个线程有自己的写入位置;
    * 3.每个线程有自己的数据缓冲区;
    * 4.写文件前, 会 加锁(全局变量), 然后 将文件句柄 跳跃到指定位置, 写下线程缓冲区的数据;
    * 5.现象: 写的是图片, 经常出现写入数据出错, 图片打不开;
    * 6.日志: 对写文件前后的 文件句柄进行位置打印, 位置正确.
            (每个线程进行写文件的)代码实现:  各线程都会打开同一个文件获取句柄, 
    void write_file(FILE* fp, char *srcContent, int Lenth, int index)
    {

    int nwrite = 0, len = 0;
    pthread_mutex_lock(&g_muetx_lock);

    printf("---------- 1 -----------\n");

    if((fseek(fp, threadWorkHandle[index].writeInitPosition , SEEK_SET)) == -1)
    {
        myprint("Err : func lseek()");
        assert(0);
    }
    myprint("pthread : %d, The write begin current : %lu, fp : %p", index, ftell(fp), fp);

    while(nwrite < Lenth)
    {

        if((len = fwrite( srcContent + nwrite, 1, Lenth - nwrite, fp)) < 0)
        {       
            myprint("Err : func fwrite()");
            assert(0);
        }       
        nwrite += len;
    }
    threadWorkHandle[index].writeInitPosition  += Lenth;
    myprint("pthread : %d, The write end  : %lu, nwrite : %d", index, ftell(fp), nwrite);

    //fflush(fp);
    printf("---------- 2 -----------\n");

    pthread_mutex_unlock(&g_muetx_lock);

    }

5个回答

文件打开是否为共享写的方式,其实对于一个文件,没必要多个线程去写,一个线程写就可以了

yyxyong
路之遥_其漫漫 业务需求, 每个线程都会去处理一部分数据, 写到指定的区域, 如果采用一个线程的写法, 实在无法想出如何去通知该线程将不同的数据块写入文件指定的区域
2 年多之前 回复

如果对于同一个文件,一个线程就可以了,如果多线程写入会出现错乱的现象

yyxyong
路之遥_其漫漫 回复陈洪杰: 写入的数据是需要进行处理的, 这步比较耗费时间, 开多线程是为了这步功能. 然后将处理后的数据写入文件的不同区域
2 年多之前 回复
qq_18895659
树先生i 回复路之遥_其漫漫: 如果都已经加锁,那更没必要使用多线程,因为你可以这样想,既然加了锁在写入文件时都是按着顺序写的,这不就是一个线程就可以实现的了么
2 年多之前 回复
yyxyong
路之遥_其漫漫 已经在写文件前进行了加锁, 并且每次都会去移动文件指针
2 年多之前 回复

请使用多线程同步技术

yyxyong
路之遥_其漫漫 这里不需要使用线程同步, 首先1. 每个线程写文件的区域是提前规划好的, 2. 每个线程写入的数据,也是本线程计算出来的, 3.每个线程都会去打开目标文件, 获取文件句柄, 4. 所以不需要同步, 各线程之间数据, 位置都互不关联, 没有做成同步的理由...
2 年多之前 回复
yyxyong
路之遥_其漫漫 代码看了, 不需要采用线程同步.
2 年多之前 回复

思路正确, 有个小BUG, 终于解决了...

baidu_29702847
七秒记忆_lmc 您好,请问您是怎么解决的呢?我多线程写的文件也出错。。。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问