梦魇得到简单的线程工作C ++ [英] Nightmare getting simple threading working C++

查看:81
本文介绍了梦魇得到简单的线程工作C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我想做的就是在另一个班级开始一个帖子。我尝试过这么多组合,但总有一个问题。



PlayerConnection.cpp:

Hi,

All I want to do is start a thread in another class. I've tried so many combinations of things but there's always an issue.

PlayerConnection.cpp:

#include "stdafx.h"
#include "PlayerConnection.h"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <vector>

typedef struct
{
	PlayerConnection* instance;
	SOCKET& socket;
} ThreadData;

int PlayerConnection::ThreadMethod(SOCKET& socket)
{// recv etc
	return 0;
	
}

void PlayerConnection::init(SOCKET& socket)
{
	this->socket = socket;

	ThreadData* td;
	td->instance = this;
	td->socket = socket;

	DWORD connection_thread;

	CreateThread(NULL, 0, ThreadProcedure, &td, 0, &connection_thread);
}

int PlayerConnection::ThreadProcedure(LPVOID p)
{
	ThreadData* ptd = (ThreadData*)p;
	return ptd->instance->ThreadMethod(ptd->socket);
}



PlayerConnection.h:


PlayerConnection.h:

#pragma once

#include <winsock.h>

class PlayerConnection
{
public:
	void init(SOCKET& socket);
	int ThreadMethod(SOCKET& socket);
	int ThreadProcedure(LPVOID p);

private:
	SOCKET socket;
	
};



问题:




Issues:

CreateThread(NULL, 0, ThreadProcedure, &td, 0, &connection_thread);



类型为int(PlayerConnection :: *)的参数(LPVOID p)与LPTHREAD_START_ROUTINE类型的参数不兼容



'PlayerConnection :: ThreadProcedure' :非标准语法;使用'&'创建指向成员的指针



我尝试过:



-------------------------------------- -----------------------


argument of type "int (PlayerConnection::*)(LPVOID p)" is incompatible with parameter of type "LPTHREAD_START_ROUTINE"
and
'PlayerConnection::ThreadProcedure': non-standard syntax; use '&' to create a pointer to member

What I have tried:

-------------------------------------------------------------

推荐答案

在这种情况下我通常做的就是理查德提及。我使用静态线程接口方法作为线程过程。创建另一个非静态方法,创建线程并将其作为参数传递。然后它调用另一个执行实际工作的非静态方法。以下是仅包含相关位的简短示例:
What I usually do in this situation is as Richard mentioned. I use a static thread interface method as the thread procedure. A make another non-static method that creates the thread and passes this as its argument. Then it calls another non-static method that does the actual work. Here is a brief example with just the relevant bits :
class CMyObject
{
    int ThreadMethod();   // do the work of the thread in this

    static int ThreadProcedure( pvoid * p )
    {
       CMyObject * pthis = (CMyObject *)p;
       return pthis->ThreadMethod();
    }

    void StartWorkThread()
    {
        // probably have to do some casting here to compile

        BeginThread( ThreadProcedure, this );  // change this to create your thread 
    }
};

有时线程方法需要一些额外的参数,所以我创建了一个小类或结构来保存参数和this指针,因为你只能将一个东西传递给线程过程。下面是一个示例:

Sometimes the thread method needs some additional arguments so I make a little class or structure to hold the arguments along with the this pointer since you can pass only one thing to the thread procedure. Here's an example of that :

typedef struct
{
   int arg1;
   double arg2;
   CSomethingElse * pse;
   CMyObject * pthis;
} ThreadData;

int CMyObject::ThreadMethod( ThreadData *ptd )
{
   // this was changed to accept the data argument

   ThreadData td;
   memcpy( &td, ptd, sizeof( ThreadData ) );   // make a copy

  // and so on....
}

void CMyObject::StartWorkThread()
{
   ThreadData td;
   td.arg1 = 42;
   td.arg2 = 3.1416;
   td.pse = nullptr;
   td.pthis = this;

   BeginThread( ThreadProcedure, &td );  // change this to create your thread
}

int CMyObject::ThreadProcedure( pvoid *p )
{
   ThreadData * ptd = (ThreadData *)p;
   return ptd->pthis->ThreadMethod( ptd );
}

您也可以将线程数据传递给ThreadMethod。复制是因为当StartWorkThread返回时,线程数据将无效。

You can pass the thread data to the ThreadMethod also. The copy is made because the thread data will be invalid when StartWorkThread returns.


使用std :: thread修复。更整洁,更现代,并以某种方式解决了这个问题。不完全确定如何,但它确实起作用。



Fixed using std::thread instead. Far neater, more modern, and somehow solves this issue. Not entirely sure how, but it does the job.

struct ThreadData
{
	PlayerConnection* instance;
	SOCKET& socket;
};

ThreadData td = { this, socket };
std::thread t(receive, td);
t.join();

void receive(ThreadData data)
{
	PlayerConnection* _this = data.instance;
	SOCKET& socket = data.socket;
	...
}


这篇关于梦魇得到简单的线程工作C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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