pybind 回调 多线程 异常

 

thread代码:

int RecvThread(SOCKET sockClient,py::function caminfocall) {

    g_caminfocall = caminfocall;
    //py::function  caminfocall = *(py::function *)pcaminfocall;
    g_caminfocall(2, 0, 2);

 

c++调用代码:

caminfocall(1, 0, 1);
    std::thread thread1(RecvThread, sockClient, caminfocall);
    thread1.detach();
    printf("tcpInit ok \n");

 

python调用代码:

def callb_camerainfo(self,cam_no,camera_info,camera_info_size):
    print("callb_camerainfo",cam_no,camera_info_size)
ret = self.cv_dll.tcp_init(ip, port,self.callb_camerainfo)

第一次第二次还能收消息,后面就收不到消息了。

临时解决方法:

加个join就能收到了,不加程序会报错:

    std::thread thread1(RecvThread, sockClient, caminfocall);
    thread1.join();

加上这句后,能收到回调了,但是引发另一个问题,

主界面卡住了。

 

c++版的CreateThread也有问题,多线程回调收不到:

 

static py::function g_caminfocall;

{

    caminfocall(-2, 0, 1);
    g_caminfocall = caminfocall;
    /*std::thread thread1(RecvThread, sockClient, caminfocall);
    thread1.detach();*/

    //HANDLE h_thread = CreateThread(NULL, 0, RecvThread, (LPVOID)sockClient, 0, NULL);
    HANDLE h_thread = CreateThread(NULL, 0, RecvThread, (LPVOID)sockClient,  0,NULL);
    CloseHandle(h_thread);
    return 0;
}

 

DWORD WINAPI RecvThread(LPVOID lpParameter){
//int RecvThread(SOCKET sockClient,py::function caminfocall) {

	SOCKET sockClient = (SOCKET)lpParameter;
	//g_caminfocall = *caminfocall;
	while (1) {
		RecStruct data_recv;
		int ret;
		memset(&data_recv, '0', sizeof(struct RecStruct));
		ret = recv(sockClient, (char *)&data_recv, sizeof(struct RecStruct), 0);  //第二个参数使用强制类型,为一个数据包  
		if (ret == 0) // server调用了close 
		{
			printf("server close");
			break;
		}
		else if (ret == SOCKET_ERROR) {// 网络错误 
			int err = WSAGetLastError();
			printf("get message %d %d %d \n", ret, SOCKET_ERROR, err);
			if (err == WSAECONNRESET || err == WSAECONNABORTED) {
				printf("tcp error %d %d \n", err, SOCKET_ERROR);
				//int n = namemap.erase(deviceId);//如果删除了会返回1,否则返回0  
			}
			break;

		}
		printf("reve type %d %d\n", data_recv.data_type, data_recv.size);
		switch (data_recv.data_type)
		{
		case 1://摄像头列表
		{
			g_caminfocall(data_recv.cam_no, data_recv.recvbuf, data_recv.size);
			//caminfocall(data_recv.cam_no, 0, data_recv.size);
		}
		break;
		case 3://异常信息
		{
			if (g_errorcall != 0)
				g_errorcall(1, 1, data_recv.error_code, 4, NULL, 0);
			break;
		}
		case 2:
		{
			char* recemsg = data_recv.recvbuf;
			int is_null = is_begin_with(recemsg, "00000");
			if (is_null == 1) {
				printf("recv type 2 00000");
				continue;
			}

			break;
		}
		default:
			break;
		}

		if (ret < 0) {
			printf("WSAStartup() failed!\n");
			return -1;
		}
		Sleep(20);
	}

	return 0;
}

 

你可能感兴趣的:(c++,pybind)