【问题标题】:pthread windows crash C++pthread windows 崩溃 C++
【发布时间】:2014-09-15 10:37:53
【问题描述】:

我想用一个线程创建一个长度为 50 的数组,完成后我想用第二个线程在每 X 秒内打印一些第一个值。同时第一个线程可以计算下一个数组。

在我尝试将计算数组中的一些值复制到一些临时变量中之前,这些线程都是有效的。我没有编译错误,但是当我运行程序时,我得到了一个 Windows 崩溃消息。

没有线程,double *newarray(); 函数可以工作。返回一个手动分配并填充数据的数组。

我在这里错过了什么?

线程 1:

 double *newarray();

 void *computingU(void *)
 {
     double * U_tmp;

     while (true)

     {      
         pthread_mutex_lock( &mutexU );

         memcpy(U_tmp,newarray(),sizeof(double)*Ulenght);

         while (!Usent);   

         Usent = false;


         memcpy(Ucmd,U_tmp,sizeof(double)*Ulenght);

         pthread_mutex_unlock( &mutexU );  

         Ucomputed = true;
     }
}

线程 2:

void *sendingCMD(void * ) {
    double * U_tmp;

    while (true)
    {

        while (!Ucomputed);

        Ucomputed = false;

        pthread_mutex_lock( &mutexU );

        memcpy(U_tmp,Ucmd,sizeof(double)*Ulenght);

        pthread_mutex_unlock( &mutexU );

        Usent = true;

        for (int i = 0; i<Ulenght; i++)
        {

           printf("i= %d, u= %f", i, U_tmp[i]);

           sleep(sleepTime) ;
        }

    }
}

主要:

#include <pthread.h>
#include <time.h>
#include <math.h>
#include <unistd.h>

using namespace std;

bool Ucomputed = false, Usent = true;
double * Ucmd;
pthread_mutex_t mutexU = PTHREAD_MUTEX_INITIALIZER;
unsigned int Ulenght = 1;
int sleepTime = 1;

int main( void )
{
    #ifdef DEBUG_THREAD
    int rc1, rc2;

    pthread_t thread1, thread2;
   /* Create independent threads each of which will execute functionC */
   if( (rc1=pthread_create( &thread1, NULL, &computingU, NULL)) )   {
      printf("Thread creation failed: %d\n", rc1);
   }

   if( (rc2=pthread_create( &thread2, NULL, &sendingCMD, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc2);
   }
    #endif //

    sleep(10);

    while (true);
}

【问题讨论】:

  • 为什么要在computingU 中两次锁定互斥锁?
  • 这是我复制代码时的错误。

标签: c++ arrays windows multithreading pthreads


【解决方案1】:

让我们使用computingU 函数中的第一个线程,那里有一个局部变量:

double * U_tmp;

稍后你使用这个变量:

memcpy(U_tmp,newarray(),sizeof(double)*Ulenght);

但是你没有初始化这个变量,所以它没有指向任何东西。由于未初始化(非静态)的局部变量具有不确定的值,所以指针U_tmp 将指向一个看似随机的位置。在那里写信会导致undefined behavior 并且很可能会导致您崩溃。

你在另一个线程中也遇到了同样的问题。

【讨论】:

    【解决方案2】:

    看看:

     double * U_tmp;
    

    您永远不会将指针设置为任何内容,然后尝试将 memcpy() 数据放入其中。每次都会100%崩溃。如果没有,你的操作系统就坏了。

    【讨论】:

    • 不保证会崩溃。很有可能。
    • 它将在 100% 的时间内粉碎堆栈,因为局部变量的总内存大小是
    • 不,它不会“100% 地粉碎堆栈”。它可能粉碎堆栈,但它也可能写入堆或未映射的页面。问题是没有办法知道指针指向的哪里,它的值是不确定的。
    • 写入堆将是一个段错误,应该由操作系统检测到。另外,在这个例子中没有堆分配可以写入,这就是我所说的原因。
    • 写入未分配空间不一定会出现段错误。写入堆栈上的随机位置不一定会导致问题(堆栈上的位置可能低于程序使用的任何位置)。你不能依赖这个导致任何不愉快的事情。
    猜你喜欢
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多