MFC对话框程序 AfxBeginThread 传参数的问题

时间:2021-11-26 14:30:26
主对话框调用 AfxBeginThread 开一个线程,如果单纯传入 this(主对话框指针),可以在线程函数内正确接收到(传入时和接收的地址打印值一致),我需要加一个标志位进去,于是定义了一个struct,如下:
struct AAA
{
    CMainDlg * pDlg;
    int nFlag;
}
给AfxBeginThread 传入了一个AAA对象的地址,示例代码如下:
AAA a;
a.pDlg = this;
a.nFlag = 1;
AfxBeginThread (Fun ,&a ,xxxxxx);
线程内接收就是
UINT Fun(LPVOID pParam)
{
    AAA *p = (AAA*)pParam;
    ...
}

这样使用的时候我发现,那个nFlag传进去都不对,打印出来是128;而pDlg也不对,
我改成下边的以后,那个nFlag传递正确了,可那个对话框指针还是时好时坏,奇怪了。
AAA *a new AAA;
a->pDlg = this;
a->nFlag = 1;
AfxBeginThread (Fun ,a ,xxxxxx);
delete a;

如果只传this的话,线程内接收的this就是始终是正确的。哪位知道原因,不吝赐教!

10 个解决方案

#1


补充一下:如果这样传参数:

AAA a;
a.pDlg = this;
a.nFlag = 1;
AfxBeginThread (Fun ,&a ,xxxxxx);
结果是这样的(测试5次的结果,两次是错的)

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1240064 线程接收的this 918B371C      // 错误

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 0 线程接收的this 00000000 // 错误

#2


上边说错了,应该是6次结果,两次是错的

#3


AAA 不用 new 的话是局部对象, 函数运行完就销毁了, 线程函数运行时间是不确定的, 有可能是你 AfxBeginThread 的函数运行完了后才开始运行的, 这是对象已经不存在了. 其行为是未定义的.

#4


引用 3 楼 adlay 的回复:
AAA 不用 new 的话是局部对象, 函数运行完就销毁了, 线程函数运行时间是不确定的, 有可能是你 AfxBeginThread 的函数运行完了后才开始运行的, 这是对象已经不存在了. 其行为是未定义的.
问题是new了以后那个this还是时好时坏

#5


使用new来做。
在线程结束时去delete

#6


引用 5 楼 zhoujielunzhimi 的回复:
使用new来做。
在线程结束时去delete
必须new吗?我记得以前做的时候就用的临时对象啊

#7


嗯, 你不能 AfxBeginThread 执行完就去 delete, 这样和局部变量是一样的. 要在 UINT Fun(LPVOID pParam) 里把参数取出来了, 确认不使用了才 delete.
或者干脆定义成 static AAA a; 就好.

#8


引用 7 楼 adlay 的回复:
嗯, 你不能 AfxBeginThread 执行完就去 delete, 这样和局部变量是一样的. 要在 UINT Fun(LPVOID pParam) 里把参数取出来了, 确认不使用了才 delete.
或者干脆定义成 static AAA a; 就好.
我使用static确实有效果。现在引入一个新问题:就是我连续执行了两次开线程的操作,第一次传入的那个nFlag=1,第二次我改成0,结果有时候第一次开的线程函数接收的nFlag就变成了0了,也就是被后边的给冲掉了,这线程函数的执行确实不容易掌握啊,没有时序性。那如何避免这个问题,就是第一次需要那个nFlag=1,第二次是0.

#9


1个静态应该不行
new是可行的; 想必是过早地delete导致第二次new地址仍相同,不然怎会有时候"冲掉"?

在线程里尾部delete a,(此后new到哪里无所谓,此前不会new同址)将实参结构体指针所占空间删除

#10


引用 9 楼 x363635334 的回复:
1个静态应该不行
new是可行的; 想必是过早地delete导致第二次new地址仍相同,不然怎会有时候"冲掉"?

在线程里尾部delete a,(此后new到哪里无所谓,此前不会new同址)将实参结构体指针所占空间删除
new现在看来是可行的,我如果不delete,它不应该会失效,也不会说和第二次new的混淆了

#1


补充一下:如果这样传参数:

AAA a;
a.pDlg = this;
a.nFlag = 1;
AfxBeginThread (Fun ,&a ,xxxxxx);
结果是这样的(测试5次的结果,两次是错的)

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 1240064 线程接收的this 918B371C      // 错误

 传入的this 0012F380
 1 线程接收的this 0012F380

 传入的this 0012F380
 0 线程接收的this 00000000 // 错误

#2


上边说错了,应该是6次结果,两次是错的

#3


AAA 不用 new 的话是局部对象, 函数运行完就销毁了, 线程函数运行时间是不确定的, 有可能是你 AfxBeginThread 的函数运行完了后才开始运行的, 这是对象已经不存在了. 其行为是未定义的.

#4


引用 3 楼 adlay 的回复:
AAA 不用 new 的话是局部对象, 函数运行完就销毁了, 线程函数运行时间是不确定的, 有可能是你 AfxBeginThread 的函数运行完了后才开始运行的, 这是对象已经不存在了. 其行为是未定义的.
问题是new了以后那个this还是时好时坏

#5


使用new来做。
在线程结束时去delete

#6


引用 5 楼 zhoujielunzhimi 的回复:
使用new来做。
在线程结束时去delete
必须new吗?我记得以前做的时候就用的临时对象啊

#7


嗯, 你不能 AfxBeginThread 执行完就去 delete, 这样和局部变量是一样的. 要在 UINT Fun(LPVOID pParam) 里把参数取出来了, 确认不使用了才 delete.
或者干脆定义成 static AAA a; 就好.

#8


引用 7 楼 adlay 的回复:
嗯, 你不能 AfxBeginThread 执行完就去 delete, 这样和局部变量是一样的. 要在 UINT Fun(LPVOID pParam) 里把参数取出来了, 确认不使用了才 delete.
或者干脆定义成 static AAA a; 就好.
我使用static确实有效果。现在引入一个新问题:就是我连续执行了两次开线程的操作,第一次传入的那个nFlag=1,第二次我改成0,结果有时候第一次开的线程函数接收的nFlag就变成了0了,也就是被后边的给冲掉了,这线程函数的执行确实不容易掌握啊,没有时序性。那如何避免这个问题,就是第一次需要那个nFlag=1,第二次是0.

#9


1个静态应该不行
new是可行的; 想必是过早地delete导致第二次new地址仍相同,不然怎会有时候"冲掉"?

在线程里尾部delete a,(此后new到哪里无所谓,此前不会new同址)将实参结构体指针所占空间删除

#10


引用 9 楼 x363635334 的回复:
1个静态应该不行
new是可行的; 想必是过早地delete导致第二次new地址仍相同,不然怎会有时候"冲掉"?

在线程里尾部delete a,(此后new到哪里无所谓,此前不会new同址)将实参结构体指针所占空间删除
new现在看来是可行的,我如果不delete,它不应该会失效,也不会说和第二次new的混淆了