C线程中pthread_create函数的第四个参数的范围

C线程中pthread_create函数的第四个参数的范围,c,multithreading,pthreads,C,Multithreading,Pthreads,有人能简单地解释一下吗?您将非常相同的指针传递给所有三个线程。所有线程都将取消引用同一指针,得到相同的值 由于您调用,指针指向的数据将不再有效。这意味着取消引用将导致 此外,由于您在没有同步的情况下访问和修改共享数据,因此数据竞争再次导致未定义的行为 前两个问题可以通过传递i的值而不是指针来轻松解决。这是少数几个大多数人认为可以把整数当作指针的情况之一。不过,您必须进行一些铸造才能使其正常工作: Thread ID: 3, Static: 2, Global: 2 Thread ID: 3, S

有人能简单地解释一下吗?

您将非常相同的指针传递给所有三个线程。所有线程都将取消引用同一指针,得到相同的值

由于您调用,指针指向的数据将不再有效。这意味着取消引用将导致

此外,由于您在没有同步的情况下访问和修改共享数据,因此数据竞争再次导致未定义的行为

前两个问题可以通过传递
i
的值而不是指针来轻松解决。这是少数几个大多数人认为可以把整数当作指针的情况之一。不过,您必须进行一些铸造才能使其正常工作:

Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6
然后,在获取值时,必须执行相反的强制转换:

pthread_create(&tid, NULL, myThreadFun, (void *) (intptr_t) i);
您将非常相同的指针传递给所有三个线程。所有线程都将取消引用同一指针,得到相同的值

由于您调用,指针指向的数据将不再有效。这意味着取消引用将导致

此外,由于您在没有同步的情况下访问和修改共享数据,因此数据竞争再次导致未定义的行为

前两个问题可以通过传递
i
的值而不是指针来轻松解决。这是少数几个大多数人认为可以把整数当作指针的情况之一。不过,您必须进行一些铸造才能使其正常工作:

Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6
然后,在获取值时,必须执行相反的强制转换:

pthread_create(&tid, NULL, myThreadFun, (void *) (intptr_t) i);
我为两个线程获得了相同的线程id,这不应该是因为myid是一个本地指针,并且每个线程的打印应该不同

myid
是一个本地指针,但它实际上指向另一个线程的地址<在您创建的所有3个线程中,code>myid都指向main中的
i
的相同地址。因此,当您取消引用myid时,所有线程都从同一位置读取

没有什么问题

  • 由于
    main
    调用,
    pthread\u exit
    ,一旦主线程退出,您就不能再从其他线程访问
    i
    。这是

  • 所有线程实际上都读取
    i
    (通过
    myid
    )。这是一个-多个线程访问
    i
    ,而没有任何 同步

  • 请注意,对象的范围并不决定对象的生存期。它们是相关的,但并不相同

    我为两个线程获得了相同的线程id,这不应该是因为myid是一个本地指针,并且每个线程的打印应该不同

    myid
    是一个本地指针,但它实际上指向另一个线程的地址<在您创建的所有3个线程中,code>myid都指向main中的
    i
    的相同地址。因此,当您取消引用myid时,所有线程都从同一位置读取

    没有什么问题

  • 由于
    main
    调用,
    pthread\u exit
    ,一旦主线程退出,您就不能再从其他线程访问
    i
    。这是

  • 所有线程实际上都读取
    i
    (通过
    myid
    )。这是一个-多个线程访问
    i
    ,而没有任何 同步


  • 请注意,对象的范围并不决定对象的生存期。它们是相关的,但不相同。

    以下建议代码:

    int myid = (int) (intptr_t) vargp;
    
  • 干净地编译
  • 执行所需的功能
  • 更正在OPs发布代码中发现的问题
  • 检查(大多数)错误情况
  • main()
    函数使用正确的签名
  • 现在建议的守则是:

    int myid = (int) (intptr_t) vargp;
    

    注意:声称是线程ID的字段只是创建线程的顺序,而不是实际的线程ID。

    以下建议的代码:

    int myid = (int) (intptr_t) vargp;
    
  • 干净地编译
  • 执行所需的功能
  • 更正在OPs发布代码中发现的问题
  • 检查(大多数)错误情况
  • main()
    函数使用正确的签名
  • 现在建议的守则是:

    int myid = (int) (intptr_t) vargp;
    

    注意:声称是线程ID的字段只是创建线程的顺序,而不是实际的线程ID。

    您期望什么输出?您期望什么输出?@p.p.我不知道
    main
    函数中
    I
    的生存期是否已结束。因为
    pthread\u exit
    不返回,这是否意味着
    main
    中所有变量的生存期将与进程的生存期相同?或者
    pthread_exit
    是否结束当前线程中所有变量的生存期?“这是否意味着main中所有变量的生存期都将与进程具有相同的生存期?”-否,它们的生存期在
    pthread_exit
    调用后结束。
    i
    的生存期在主线程退出时结束,即调用
    pthread\u exit
    时(或进程退出时)。只要调用了
    pthread\u exit
    ,就应该认为它的所有资源都不再被其他线程访问。@一些程序员朋友,根据你的回答,如果myid指针保持值3,那么它就不能移到1或2,这意味着线程ID:2,静态:4,全局:4线程ID:3,静态:6,全局:6线程ID:1,静态:2,全局:2这是不可能的。@Shivanshu在您的程序中,
    s
    g
    之间没有太大区别。两者都是“全局的”(它们的生存期在进程退出之前有效),它们的访问会导致数据竞争
    myid
    也有同样的问题(但它不是“全局的”——它的生命周期仅限于主线程),但它也有另一个问题。@Shivanshu你有这个问题,这使你的程序不可靠,而且完全是错误的。争论这件事没有意义