【问题标题】:pthread argument address is different than beforepthread 参数地址与以前不同
【发布时间】:2016-08-26 04:07:08
【问题描述】:

我创建了 2 个线程,main() 会将 argc 和 argv 传递给线程,所以我使用包含 argcargvstruct arg

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct arg {
   int argc;
   char id[9];
   char **argv;
};

int test1(struct arg *a) {
    int argc;
    char **argv;
    argc = a->argc;
    argv = a->argv;

    if (argc > 3) {
        printf("arg 1 is %s, arg 2 is %s arg 3 is %s\n\n", *(argv+1), *(argv+2),a->id);
    }
    else {
        exit(0);
    }


    return 0;
}
int main(int argc, const char *argv[]) {
    int i;
    void *ret;
    struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));
    pthread_t *thread = (pthread_t *) malloc(sizeof(*thread) * atoi(argv[3]));

    for(i = 0; i < atoi(argv[3]); ++i) {
        a[i].argc = argc;
        a[i].argv  = argv;
        sprintf(a[i].id,"%d",i);
        pthread_create( &thread[i], NULL , test1 ,(struct arg *)&(a[i]));
    }

    for(i = 0; i < atoi(argv[3]); ++i) {
         pthread_join( thread[i], &ret);
    }

    return 0;
}

我执行我的程序:

./test 1 2 2

输出如下:

arg 1 is 1, arg 2 is 2 arg 3 is 0

arg 1 is , arg 2 is  arg 3 is 1

在线程 1 中,argv 是正确的,但在线程 2 中,argv 地址与之前不同。

我用gdb打印a->argv地址

  • 在主 argv 地址是 0x7fffffffdee8
  • 在线程 1 的 argv 地址是 0x7fffffffdee8
  • 在线程 2 的 argv 地址是 0x7ffff6fef700

[切换到线程 0x7ffff6fef700 (LWP 19472)]

argv地址与线程地址相同

我在 pthread_create 之前检查 arg[1]->argv

地址是0x7fffffffdee8。

pthread_create会改地址吗?

我有什么遗漏吗?

【问题讨论】:

  • 您应该将argv[3] 转换为整数一次(并检查它是否不是零、负数或太大),而不是每次需要该数字时都转换。

标签: c linux multithreading


【解决方案1】:

这一行

struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));

没有分配正确的内存量。应该是sizeof(struct arg)。您正在分配一个由 n 个结构组成的数组,因此您需要结构本身的大小,而不是指向它的指针。

我必须清理很多东西才能编译它。您应该在编译器中打开警告并修复它们。

【讨论】:

    【解决方案2】:

    在这一行中,您分配的空间太少:

    struct arg *a = (struct arg *) malloc(sizeof(struct arg *) * atoi(argv[3]));
    

    应该更像:

    struct arg *a = (struct arg *) malloc(sizeof(*a) * atoi(argv[3]));
    

    你不应该篡改main()的定义; const 不是其类型的一部分(请参阅What should main() return in C and C++,它还涵盖了参数和返回值)。

    你还应该让你的线程函数符合void *test1(void *vp);那是线程函数的类型。例如:

    static void *test1(void *vp)
    {
        struct arg *a = vp;
        int argc = a->argc;
        char **argv = a->argv;
        …
    

    pthread_create() 调用中的演员是没有根据的。

    【讨论】:

      猜你喜欢
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 2012-12-16
      • 2015-02-17
      • 2013-09-05
      相关资源
      最近更新 更多