c - pthreads : difference due to malloc and direct declaration

标签 c pthreads

我在 pthreads 中做了一个简单的程序,它通过结构将多个参数传递给被调用的函数。考虑这两个程序:
程序 1:

#include <pthread.h>
#include <stdio.h>
#include <malloc.h>

struct args{
    long long val1;
    int val2;
};

void *hello(void* threadid){
    struct args *tid;
    tid=(struct args*)threadid;
    printf("thread %lld\n",tid->val1);
    pthread_exit(NULL);
}

int main(){
    pthread_t threads[20];
    int i;
    for(i=0;i<20;i++){
        // ***** specific memory given to the struct *****
        struct args* a1=(struct args*)malloc(sizeof(struct args));    
        a1->val1=i;
        a1->val2=i+1;
        int ret=pthread_create(&threads[i],NULL,hello,(void*)a1);
        if(ret){
            printf("error code %d for %d\n",ret,i);
        }
    }
    pthread_exit(NULL);
}

按预期打印输出,0..19

的一些排列

另一方面,考虑 程序p2

#include <pthread.h>
#include <stdio.h>

struct args{
    long long val1;
    int val2;
};

void *hello(void* threadid){
    struct args *tid;
    tid=(struct args*)threadid;
    printf("thread %lld\n",tid->val1);
    pthread_exit(NULL);
}

int main(){
    pthread_t threads[20];
    int i;
    for(i=0;i<20;i++){
        // ***** struct made like normal declarations *****
        struct args a1;
        a1.val1=i;
        a1.val2=i+1;
        int ret=pthread_create(&threads[i],NULL,hello,(void*)&a1);
        if(ret){
            printf("error code %d for %d\n",ret,i);
        }
    }
    pthread_exit(NULL);
}

这个程序有重复和不完整的条目,比如

thread 3
thread 5
thread 3
thread 4
thread 3
thread 6
thread 7
thread 8
thread 9
thread 10
thread 11
thread 12
thread 13
thread 15
thread 15
thread 16
thread 17
thread 18
thread 19
thread 19

为什么struct的实例化直接造成这种重叠? C 不应该为循环中的每次提供一个新的内存块吗?

最佳答案

在您的第二个示例中,a1for 循环中声明为具有自动存储持续时间。这意味着在每次迭代结束时,该存储位置可以然后被重新用于下一次迭代。因此:

int ret=pthread_create(&threads[i],NULL,hello,(void*)&a1);

...您可能将地址 (&a1) 传递到将在后续迭代中修改的内存位置。另一方面,malloc 会在每次迭代时分配一个指向不同内存位置的指针。

由于无法保证线程是否会在下一次迭代开始之前或之后执行,因此每次运行上述代码时,您实际上可能会得到不同的结果。

此外,使用 malloc 而不将指针存储在任何地方或在线程中释放它们将导致内存泄漏。在所有线程完成之前,您的结构也可能超出范围,结果是它们访问了一个悬空指针。最后,由于您没有加入任何线程,因此无法确定在程序退出之前有多少线程会真正执行完。

欢迎来到奇妙的多线程世界。

关于c - pthreads : difference due to malloc and direct declaration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14836679/

相关文章:

c - 如何使用 pthread 并行化嵌套循环?

c - 全局指针引用的局部变量

c - 在不共享其源代码的情况下在 matlab 中运行 C 函数

C - 为包含字符串的表动态分配内存

c - 对循环中的信号进行非阻塞检查

c++ - 使用 pthread 同时 push() 到共享队列?

c - 为什么复合赋值中不允许使用一元运算符?

c - 通过汇编查找数组的维度

linux - 多个进程中的pthread_mutex_t...谁破坏了它?

c - 在 pthread_create() 中,在创建的线程退出之前释放 args 时的行为