Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 双重释放或损坏(!prev)pthread_C_Multithreading - Fatal编程技术网

C 双重释放或损坏(!prev)pthread

C 双重释放或损坏(!prev)pthread,c,multithreading,C,Multithreading,我在实现多线程程序时遇到问题。 对于单个线程(当我将THREADS设置为1时),该程序似乎工作正常,但是对于NTHREADS>1,我得到以下错误: 分段故障(堆芯转储) 或 双重免费或损坏(!prev) 或 free():无效大小:0xb6b00a10*** 0中止(堆芯转储) 正如你所看到的,错误变化很大,我感到困惑 我正在执行的程序如下所示: #include <stdio.h> #include <stdlib.h> #include <math.h>

我在实现多线程程序时遇到问题。 对于单个线程(当我将THREADS设置为1时),该程序似乎工作正常,但是对于NTHREADS>1,我得到以下错误:
分段故障(堆芯转储)

双重免费或损坏(!prev)

free():无效大小:0xb6b00a10***
0中止(堆芯转储)

正如你所看到的,错误变化很大,我感到困惑

我正在执行的程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <pthread.h>
#define NTHREADS 5
typedef struct data_t
{
    int num;
    FILE *fp;
    pthread_mutex_t mutex;
    int thread_id;
}data_t;

void writefp(int num1, FILE *fp){
    if(fp!=NULL){
        int i;
        int nume = 1;
        int long_var=log10(nume);
        for(i=long_var;i>=0;i--){
            nume=(num1 / (int) round(pow(10, i)) % 10);
            char d=nume+'0';
            fwrite(&d, 1, 1, fp);
            printf("%c", d);
        }
    }
    fclose(fp);
}

void *thread_writefp(void* args)
{
    data_t *data = (data_t *)args;
    printf(" Thread id %d\n", data->thread_id);

    pthread_mutex_lock(&(data->mutex));
    writefp(data->num, data->fp);
    pthread_mutex_unlock(&(data->mutex));
    pthread_exit(NULL);
}
int randomf(){
    int num,i;
    for(i = 0; i<2; i++) {
        num = rand()%100000+1;
    }
    return num;
}

int prime(int num1){
    int is_prime=1;
    int i = 2;
    printf("Number: ");
    while( i<=num1/2 && is_prime==1 ) {
        printf("%i ", i);
        if(i%30==0){
            printf("\n");
        }
        if( num1 % i == 0 ) {
                is_prime = 0;
        }
        i++;
    }
    printf("\n");
    if(is_prime){
            printf("%i is number prime\n", num1);
    }else{
             printf("NO is prime %i\n",num1);
    }
    return 0;
}


int main(void){
    int i;
    //int num1=randomf();
    srand(time(NULL));
    FILE *fp = fopen("fich.txt", "w+b");

    data_t data;
    pthread_t consumers_thread[NTHREADS];
    data.mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
    data.fp = fp;

    //writefp( num1, fp);
    for(i = 0; i < NTHREADS; i++)
    {
        data.num = randomf();
        data.thread_id = i;
        printf("Number prime is %i\n", prime(data.num));
        if(pthread_create(&consumers_thread[i], NULL, 
                    thread_writefp, (void*) &data) != 0)
        {
            fprintf(stderr, "%s\n", "Error creating thread!");
            return EXIT_FAILURE;
        }
    }
    // wait for all consumers thread to finish
    for(i = 0; i < NTHREADS; ++i)
    {
        pthread_join(consumers_thread[i], NULL);
    }
    return EXIT_SUCCESS;
}
下面是我在不更改代码的情况下连续使用
gdb
树运行时得到的树错误示例:

1. 2. 3.
线程3“consummer”接收到信号SIGABRT,已中止。
[切换到线程0xb74c0b40(LWP 18143)]
内核vsyscall()中的0xb7fd7cf9
(gdb)英国电信
#内核vsyscall()中的0 0xb7fd7cf9
#1 0xb7cf17e2位于../sysdeps/unix/sysv/linux/nptl signals处的uu_libc_signal_restore_set(set=0xb74bfe9c)中。h:80
#在../sysdeps/unix/sysv/linux/raise.c:48处有2个GI-raise(sig=6)
#3 0xb7cf2f51在中止处的uuu GI_中止()中。c:90
#4 0xb7d340cc在../sysdeps/posix/libc_fatal.c:181处的u libc_消息中(操作=(do_abort | do_backtrace),fmt=)
#malloc_printerr中的5 0xb7d3af5d(操作=,str=0xb7e418d8“双重释放或损坏(!prev)”,ptr=,和,
ar_ptr=0xb7e967a0)在malloc.c:5425
#6 0xb7d3bb3b在内部自由(av=0xb7e967a0,p=,have_lock=have_lock@entry=0)在malloc.c:4174
#malloc处的7 0xb7d3fcb0在自由空间(mem=0x404160)。c:3144
#在malloc.c:3004处的tcache_thread_freeres()中的8 0xb7e2587d
#9 0xb7e258c2在线程freeres处的_libc_thread_freeres()中。c:29
#在pthread_create.c:478处的start_线程(arg=0xb74c0b40)中有10个0xb7ea03ad
#位于../sysdeps/unix/sysv/linux/i386/clone.S:108的clone()中的11 0xb7dbb0a6
(gdb)
我想感谢你的帮助,请你知道我做错了什么。提前谢谢

Per(但请参见编辑2),多个线程无法安全地访问同一
文件*fp
。正如@IlyaBursov所指出的,在所有线程中只有一个
data\t data
共享,因此,只有一个
文件*
data.fp

感谢您注意到您将
fopen
移到了thread函数中。这样,每个线程独立地打开和关闭文件,因此线程之间不存在
file*
共享

这似乎取决于实现——我无法用gcc 6.4.0在Cygwin x64上重现该问题。我怀疑互斥的效果也可能因实现而异。它也可能取决于编译器选项-请参阅

Edit正如@MichaelDorgan所指出的,在其他线程正在使用的
文件*
上调用
fclose
也是一个坏主意


编辑2正如@JohnBollinger所指出的,现在。这表明在另一个线程尝试访问该文件之前,
fclose
可能是问题所在。然而,我想知道OP的stdio实现是否在某种程度上不一致。我认为,访问一个已关闭的文件时,a只会返回错误,而不会崩溃。请参阅下面的进一步评论。

您知道您的所有线程都使用了相同的
数据实例
变量,因此您的所有线程都得到了完全相同的值?请删除部分代码,直到找到与您的问题无关的问题为止(仍然)但是您的
randomf
函数仍然没有因为循环而变得更好或更随机。循环几乎毫无用处。@IlyaBursov捕捉得很好-这意味着多个线程试图同时访问同一个
文件*fp
=(编辑我怀疑互斥锁没有帮助,因为从一个线程的角度来看,状态正在更改而没有通知它。但是,我对stdio实现的了解还不够确定。)不要认为您想
fclose()
在你的
writefp
线程中,其他人也在使用它,因为他们都共享相同的fp。对不起,你引用的另一个答案是错误的,至少就当前的标准而言是错误的。@JohnBollinger你能给我指出更正吗?然后我会编辑答案。编辑我刚刚看到你的其他评论-是吗“同一流”由当前标准中的“同一
文件*
”或其他方式定义?谢谢!我们有“[a
文件
]是一种能够记录控制流所需的所有信息的对象类型”(C2011,)和”用于控制流的文件对象的地址可能很重要;文件对象的副本不必代替原始文件”(C2011),以及附近的一些其他线程。这并不像人们希望的那样明确,但没有一种可行的解释不能有效地将锁定要求应用于
文件
s。关于编辑2,我相信一个线程试图一个接一个地写入该文件,这至少是一个严重的问题它本身似乎足以解释OP报告的错误。
$gcc -pthread -Wall -o consummer consummer.c -lm 
Thread 2 "consummer" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7cc1b40 (LWP 18122)]
tcache_thread_freeres () at malloc.c:3003
3003    malloc.c: No such file or directory.
(gdb) bt
#0  tcache_thread_freeres () at malloc.c:3003
#1  0xb7e258c2 in __libc_thread_freeres () at thread-freeres.c:29
#2  0xb7ea03ad in start_thread (arg=0xb7cc1b40) at pthread_create.c:478
#3  0xb7dbb0a6 in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:108
(gdb) 
Thread 3 "consummer" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb72ffb40 (LWP 18131)]
0xb7d2af2b in __GI__IO_fwrite (buf=0xb72ff30f, size=1, count=1, fp=0x404160) at iofwrite.c:37
37  iofwrite.c: No such file or directory.
(gdb) run
Thread 3 "consummer" received signal SIGABRT, Aborted.
[Switching to Thread 0xb74c0b40 (LWP 18143)]
0xb7fd7cf9 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fd7cf9 in __kernel_vsyscall ()
#1  0xb7cf17e2 in __libc_signal_restore_set (set=0xb74bfe9c) at ../sysdeps/unix/sysv/linux/nptl-signals.h:80
#2  __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:48
#3  0xb7cf2f51 in __GI_abort () at abort.c:90
#4  0xb7d340cc in __libc_message (action=(do_abort | do_backtrace), fmt=<optimized out>) at ../sysdeps/posix/libc_fatal.c:181
#5  0xb7d3af5d in malloc_printerr (action=<optimized out>, str=0xb7e418d8 "double free or corruption (!prev)", ptr=<optimized out>, 
ar_ptr=0xb7e967a0 <main_arena>) at malloc.c:5425
#6  0xb7d3bb3b in _int_free (av=0xb7e967a0 <main_arena>, p=<optimized out>, have_lock=have_lock@entry=0) at malloc.c:4174
#7  0xb7d3fcb0 in __GI___libc_free (mem=0x404160) at malloc.c:3144
#8  0xb7e2587d in tcache_thread_freeres () at malloc.c:3004
#9  0xb7e258c2 in __libc_thread_freeres () at thread-freeres.c:29
#10 0xb7ea03ad in start_thread (arg=0xb74c0b40) at pthread_create.c:478
#11 0xb7dbb0a6 in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:108
(gdb)