传递给CreateThread()的指针的线程安全 [英] Thread Safety for Pointers passed to CreateThread()

查看:82
本文介绍了传递给CreateThread()的指针的线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨.

我正在编写一个使用TCP/IP的小型服务器应用程序.在古典风格中,我等待"WSAAccept"解除阻塞,并启动一个新线程,以处理接收到的客户端套接字.
我还使用一种结构,将信息传递给线程函数.
现在,父线程可能会再次循环(并在Thread函数有机会获取Param指向的值之前修改"CreateThread"获得指针的结构.

下面是一个代码片段.

Hi.

I am writing a Small Server app, which uses TCP/IP. In the classical style, i wait for ''WSAAccept'' to unblock, and start a New thread, to process the Client Socket received.
I also use a Structure, to pass information on to the thread function.
Now, the Parent Thread may Loop again (and Modify the Structure to which ''CreateThread'' got a pointer before the Thread Function has had a chance to take the values that the Param pointed at.

Below is a Code Snippet.

struct THR_INFO{
	CSgSrvrCore* pThis;
	SOCKET hSocket;
};


typedef THR_INFO* LP_THR_INFO;

void Class::Function(){

	// Other Code

	THR_INFO* pThrInfo;

	DWORD dwThreadID;
	THR_INFO* pThrInfo;

	#ifdef PARANOID
		pThrInfo=new THR_INFO;
		pThrInfo->pThis=this;
		pThrInfo->hSocket=h_sockClient;
	#else

		THR_INFO ThrInfo={this,h_sockClient};
		pThrInfo=&ThrInfo;
	#endif

	CreateThread(0, 0, ConnectToClientThread, pThrInfo, 0, &dwThreadID);


	//Other Code
}

//static 
void Class::ConnectToClientThread(void* pParam){

	LP_THR_INFO pThrInfo=(LP_THR_INFO)p_Param;
	SOCKET h_sockClient=pThrInfo->hSocket;
	Class* pThis=pThrInfo->pThis;
	ASSERT(pThis);

	#ifdef PARANOID
         // The Item was Created with 'new'
		delete p_Param;
	#endif


}




我应该不是PARANOIDE,并且基本功能是安全的,还是应该包含其他同步对象.

此致:)




Should I not be PARANOIDE, and the basic function will be thead safe, or should I include further Synchronisation Objects.

Regards :)

推荐答案

[已编辑,以纠正我误读了原始代码中的内容的事实]

从外观上看,如果打开PARANOID,它是线程安全的"

实际上,您是按值将指针传递给创建的线程.这实质上是在创建的线程的本地堆栈上创建指针的副本,因此,理论上,对主代码中的指针本身进行的任何修改(您执行另一个新建")都不会影响任何线程(pParam)拥有的副本).也就是说,指针指向的结构"当然是一旦将指针传递给创建的线程就不应修改的结构.初始化结构,然后放开它.完成后,您应该删除"该对象.主线程执行新"操作,并将结构的所有权/责任传递给创建的线程.该线程应自行清理,以避免内存泄漏.

关闭PARANOID后,您将在"Function()"的本地堆栈上实例化ThrInfo结构,并将指针传递给该结构.本地堆栈结构可以是临时的,并且在函数退出时会超出范围,因此您的线程具有指向某些堆栈内存的指针,这些内存可能被主线程的进一步执行所覆盖.

基本线程规则:不要将指针传递给本地堆栈对象,您会后悔的.
[edited to correct the fact that I misread something in the original code]

From the looks of it, it''s "thread safe" if you turn on PARANOID

You are, in reality, passing a pointer by value to the created thread. That essentially creates a copy of the pointer on the local stack of the created thread so, in theory, any modification to the pointer itself in the main code (you do another "new") should not affect the copy owned by any thread (pParam). Now, that said, the "structure" that the pointer points to is, of course, something that you shouldn''t modify once you pass the pointer to the created thread. Initialize the structure and then let it go. And you should "delete" the object when you are done with it. The main thread did the "new" and passed ownership / responsbility for the structure to the created thread. That thread should clean up after itself to avoid memory leaks.

With PARANOID turned off, you are instantiating your ThrInfo structure on the local stack of the "Function()" and passing the pointer to that. Local Stack structures can be temporary and go out of scope when the function exits so your thread has a pointer to some stack memory that may be overwritten by the main thread''s further execution.

Cardinal Rule of Threading: Do not pass pointers to local stack objects, you will regret it.


这篇关于传递给CreateThread()的指针的线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆