CreateThread创建的线程怎么停止

时间:2022-05-07 18:26:27
我用CreateThread()函数创建了一个线程,但在程序退出的时候出现内存不能为read的错误,我怀疑是没有停止线程引起的。哪位高手知道用什么函数能把那个线程停止?

11 个解决方案

#1


线程函数 return 就停止了

#2


添加一个退出标志,当要退出将其设置为false;

#3


在创建之初要调用CloseHandle来释放新建线程的句柄。不然在线程函数推出时,其线程内核对象的使用计数还是1,就会发生错误了。

#4


在线程创建之后,要马上调用CloseHandle ,使内核对象使用计数减去1 。

#5


在创建之初要调用CloseHandle来释放新建线程的句柄。不然在线程函数推出时,其线程内核对象的使用计数还是1,就会发生错误了。
会出现错误嘛,进程退出时会消灭一切东西。即使线程内核对象的使用计数是一。它也会正常释放内核对象的。
把代码拿出来,看看。

#6


专家说,用CreateThread不好,应该用_beginthreadex(真的这样吗?)
支持楼上两个专家

#7


进程退出了线程一定会退出的,不调用CloseHandle应该也没有问题,估计是内存、指针之类的错。

#8


bjnix() :
专家说,用CreateThread不好,应该用_beginthreadex(真的这样吗?)
支持楼上两个专家
     是这样的,因为_beginThreadex是运行时的库函数,它做了一些必要的初始化然后调用CreateThread这个API函数。

#9


为什么不调用CreateThread()创建线程?

    大多数C/C++运行时库函数都是线程安全的函数,不需要tiddata结构。但是,如果有一个线程调用了需要tiddata结构的C/C++运行时库函数时,将会发生下述情况。
    C/C++运行时库函数试图通过调用TlsGetValue()获取线程的tiddata数据块的地址。如果返回NULL作为该地址,线程就没有tiddata块与该地址相关。这时,C/C++运行时库函数就在现场为线程分配一个tiddata块,并对它进行初始化。然后该tiddata块通过TlsGetValue()函数与线程相关联。此时,只要线程在运行,该tiddata块就与该线程绑在一起,C/C++运行时库函数就可以使用该线程的tiddata块,而且将来被调用的所有C/C++运行时函数也能使用该tiddata块。
    尽管以上线程运行时几乎没有任何障碍,但是实际上还是存在一些问题。
    首先,如果线程使用C/C++运行时库的signal函数,那么整个进程就会终止运行,因为结构化异常处理帧尚未准备好。
    第二,如果不是调用_endthreadex()来终止线程的运行,那么数据块就不会被撤消,内存泄露就会出现。
    因此不应该使用CreateThread()函数创建线程

#10


据我了解,如果开发的程序需要考虑跨平台的 C/C++ 代码,应该用 _endthreadex ,如果不必考虑代码跨平台的话,就无所谓,因为在 windows 的平台内,_endthreadex 的源代码里面是调用了 CreateThread

#11


修正一下:

据我了解,如果开发的程序需要考虑跨平台的 C/C++ 代码,应该用 _beginthreadex,如果不必考虑代码跨平台的话,就无所谓,因为在 windows 的平台内,_beginthreadex 的源代码里面是调用了 CreateThread

#1


线程函数 return 就停止了

#2


添加一个退出标志,当要退出将其设置为false;

#3


在创建之初要调用CloseHandle来释放新建线程的句柄。不然在线程函数推出时,其线程内核对象的使用计数还是1,就会发生错误了。

#4


在线程创建之后,要马上调用CloseHandle ,使内核对象使用计数减去1 。

#5


在创建之初要调用CloseHandle来释放新建线程的句柄。不然在线程函数推出时,其线程内核对象的使用计数还是1,就会发生错误了。
会出现错误嘛,进程退出时会消灭一切东西。即使线程内核对象的使用计数是一。它也会正常释放内核对象的。
把代码拿出来,看看。

#6


专家说,用CreateThread不好,应该用_beginthreadex(真的这样吗?)
支持楼上两个专家

#7


进程退出了线程一定会退出的,不调用CloseHandle应该也没有问题,估计是内存、指针之类的错。

#8


bjnix() :
专家说,用CreateThread不好,应该用_beginthreadex(真的这样吗?)
支持楼上两个专家
     是这样的,因为_beginThreadex是运行时的库函数,它做了一些必要的初始化然后调用CreateThread这个API函数。

#9


为什么不调用CreateThread()创建线程?

    大多数C/C++运行时库函数都是线程安全的函数,不需要tiddata结构。但是,如果有一个线程调用了需要tiddata结构的C/C++运行时库函数时,将会发生下述情况。
    C/C++运行时库函数试图通过调用TlsGetValue()获取线程的tiddata数据块的地址。如果返回NULL作为该地址,线程就没有tiddata块与该地址相关。这时,C/C++运行时库函数就在现场为线程分配一个tiddata块,并对它进行初始化。然后该tiddata块通过TlsGetValue()函数与线程相关联。此时,只要线程在运行,该tiddata块就与该线程绑在一起,C/C++运行时库函数就可以使用该线程的tiddata块,而且将来被调用的所有C/C++运行时函数也能使用该tiddata块。
    尽管以上线程运行时几乎没有任何障碍,但是实际上还是存在一些问题。
    首先,如果线程使用C/C++运行时库的signal函数,那么整个进程就会终止运行,因为结构化异常处理帧尚未准备好。
    第二,如果不是调用_endthreadex()来终止线程的运行,那么数据块就不会被撤消,内存泄露就会出现。
    因此不应该使用CreateThread()函数创建线程

#10


据我了解,如果开发的程序需要考虑跨平台的 C/C++ 代码,应该用 _endthreadex ,如果不必考虑代码跨平台的话,就无所谓,因为在 windows 的平台内,_endthreadex 的源代码里面是调用了 CreateThread

#11


修正一下:

据我了解,如果开发的程序需要考虑跨平台的 C/C++ 代码,应该用 _beginthreadex,如果不必考虑代码跨平台的话,就无所谓,因为在 windows 的平台内,_beginthreadex 的源代码里面是调用了 CreateThread