C++ 奇怪的线程执行顺序?

C++ 奇怪的线程执行顺序?,c++,c,multithreading,pthreads,C++,C,Multithreading,Pthreads,我写了一个小程序来查看创建线程的开销 以下是程序(我写得很快,所以不是最好的): 这意味着第一个线程最后完成 那么,我的朋友们,有人对这种现象有可能的解释吗?首先,你要把一个局部变量的地址传递给线程,这个线程是不断变化的。因此,当线程有时间读取它时,i的内容就已经改变了。 为什么不能只传递i而不是&i,其中变量只有4个字节(即适合指针) 其次,您不应该担心操作系统如何调度线程。这在很大程度上取决于内核调度器实现,也可能取决于pthread库,而且线程的执行顺序永远无法保证。为了加速pthread

我写了一个小程序来查看创建线程的开销

以下是程序(我写得很快,所以不是最好的):

这意味着第一个线程最后完成


那么,我的朋友们,有人对这种现象有可能的解释吗?

首先,你要把一个局部变量的地址传递给线程,这个线程是不断变化的。因此,当线程有时间读取它时,
i
的内容就已经改变了。 为什么不能只传递
i
而不是
&i
,其中变量只有4个字节(即适合指针)


其次,您不应该担心操作系统如何调度线程。

这在很大程度上取决于内核调度器实现,也可能取决于pthread库,而且线程的执行顺序永远无法保证。为了加速pthread的正常使用,已经做了很多优化,而您的示例并不是这样。

您的代码正在打印脏数据。没有内存障碍,所以数据实际上是垃圾。最重要的是,您不会等待线程退出,因此在启动所有线程之前,进程很可能会终止。要实现(或多或少)您想要的,请尝试以下方法:

#include <iostream>
#include <pthread.h>

void * lala(void * cake) {
 int * hi = (int *)cake;
 std::cout << *hi << '\n';
}

int main(void) {
 int data[10000];
 pthread_t t[sizeof (data) / sizeof (data[0])];
 for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
   data[i] = i;
 }

 for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
  pthread_create(&t[i], 0, lala, &data[i]);
 }

  for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
  pthread_join (t[i], NULL);
 }

}
#包括
#包括
虚空*拉拉(虚空*蛋糕){
int*hi=(int*)蛋糕;

正如Ajay所指出的,您正在传递一个指向局部变量的指针,该局部变量一直在更改,一旦它超出范围(当for完成时),对它的访问就是未定义的行为

无论如何,您应该向线程传递一个指向堆分配变量的指针。您可以通过
malloc()
new
获得该指针。例如:

void * lala(void * cake) {
    int hi = *(static_cast<int *>(cake));
    delete cake; //we don't need it anymore, delete to avoid a leak

    std::cout << hi << '\n';
}

int main(void) {
    pthread_t thread;

    for (int i = 0;i < 10000;i = i + 1) {
        int * pie = new int;
        *pie = i;
        pthread_create(&thread,0,lala,pie);
    }
}
void*lala(void*cake){
int hi=*(静态_铸造(蛋糕));
删除蛋糕;//我们不再需要它,请删除以避免泄漏

std::cout-Oh…我明白了…这就解释了。谢谢。@Ajay:很好的捕获。但即使有了修复,你也可能会看到线程调度的类似奇怪之处。如果你不使用同步原语来排序线程,谁能说会发生什么呢?
pthreads
当然不会。@Michael,我已经提到过,操作系统可能会在它(内核)喜欢的方式。同步原语和线程调度是不同的概念,尽管它们来自同一个域。什么编译器?我没有得到类似的行为。@sje397:因为它是随机的:)@sje397:这种行为可能更依赖于平台而不是编译器(包括系统上有多少内核)。
#include <iostream>
#include <pthread.h>

void * lala(void * cake) {
 int * hi = (int *)cake;
 std::cout << *hi << '\n';
}

int main(void) {
 int data[10000];
 pthread_t t[sizeof (data) / sizeof (data[0])];
 for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
   data[i] = i;
 }

 for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
  pthread_create(&t[i], 0, lala, &data[i]);
 }

  for (int i = 0; i < sizeof (data) / sizeof (data[0]); ++i)
 {
  pthread_join (t[i], NULL);
 }

}
void * lala(void * cake) {
    int hi = *(static_cast<int *>(cake));
    delete cake; //we don't need it anymore, delete to avoid a leak

    std::cout << hi << '\n';
}

int main(void) {
    pthread_t thread;

    for (int i = 0;i < 10000;i = i + 1) {
        int * pie = new int;
        *pie = i;
        pthread_create(&thread,0,lala,pie);
    }
}