免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5021 | 回复: 7
打印 上一主题 下一主题

局部变量地址不能做为线程参数吗! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-27 12:51 |只看该作者 |倒序浏览

  1. typedef struct Task_Param_s
  2. {
  3.         int iSock;                                                /* 客户端socket */
  4.         struct sockaddr_in server_addr;        /* 服务器地址 */
  5. }Task_Param_t;
  6. void TaskConnect(void *arg)
  7. {
  8.         Task_Param_t *pstParam;

  9.         if(NULL == arg)
  10.         {
  11.                 ASSERT(0);
  12.                 return;
  13.         }
  14.         pstParam = (Task_Param_t *)arg;
  15.         if(connect(pstParam->iSock,&pstParam->server_addr,sizeof(struct sockaddr_in)) == -1)
  16.         {
  17.                 printf("[%s:%d]connect %s:%d error\r\n",
  18.                         __FILE__, __LINE__, inet_ntoa(pstParam->server_addr.sin_addr), ntohs(pstParam->server_addr.sin_port));
  19.                 return;
  20.         }
  21. }

  22. int test()
  23. {
  24.         pthread_t id;
  25.         Task_Param_t stConnectParam;
  26.         int iClientSock = -1;
  27.         iClientSock = socket(AF_INET, SOCK_STREAM, 0);
  28.         stConnectParam.server_addr.sin_family = AF_INET;
  29.         stConnectParam.server_addr.sin_port = htons(POST);
  30.         stConnectParam.server_addr.sin_addr.s_addr = inet_addr(ADDR);       
  31.         printf("[%s:%d]connect %s:%d\r\n",
  32.                         __FILE__, __LINE__, inet_ntoa(stConnectParam.server_addr.sin_addr), ntohs(stConnectParam.server_addr.sin_port));

  33.         if(pthread_create(&id, NULL, TaskConnect, &stConnectParam))
  34.         {
  35.                 printf("create connect task failed\r\n");
  36.                 return ERROR;
  37.         }
  38. }


复制代码

[Client.c:395]connect 192.168.2.38:3333
[Client.c:341]connect 114.3.204.0:36352 error

在网上找了一下,线程参数要么用全局变量,要么malloc分配空间,这样的话就没有上面的问题
问题
1、为什么这里局部变量地址不能这样用,我平时在普通的函数调用都是这样用?
2、我在test函数和TaskConnect函数中将传入参数&stConnectParam和pstParam的地址打印出来了
是一样的,难道pthread_create时将该局部变量的地址篡改了?

[ 本帖最后由 天冷就回来 于 2007-4-27 13:03 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-04-27 12:57 |只看该作者
没有详细看。

各THREAD的STACK是不同的

评分

参与人数 1可用积分 +2 收起 理由
langue + 2

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2007-04-27 13:04 |只看该作者
没有人可以说说吗!

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2007-04-27 13:20 |只看该作者
你的两个线程读写同一个地址的内容
发生竞争
结果不可预测

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
5 [报告]
发表于 2007-04-27 13:46 |只看该作者
stConnectParam退出test函数就不存在了

论坛徽章:
0
6 [报告]
发表于 2007-04-27 13:55 |只看该作者

这样做不规范也造成了隐患

函数内的局部变量是存储在栈中,一旦函数结束,栈中的该变量就会处于栈指针之上(已出栈),若之后再有压栈操作这个地址的变量就会改变。
因此你再次调用相同地址的指针读取该地址时,可能已经变化了,更危险的时如果你通过指针改变该值可能会导致其他函数调用出现错误。
所以尽量不要写这种不规范代码,否则导致后期调试的复杂。

评分

参与人数 1可用积分 +3 收起 理由
langue + 3

查看全部评分

论坛徽章:
0
7 [报告]
发表于 2007-04-27 14:01 |只看该作者
局部变量可以作为线程的参数,但是你要确保该线程退出前,该局部变量依然存在.
一般来说你需要在test函数对该线程进行join操作(pthread_create之后),等线程退出后,test函数再退出.

论坛徽章:
0
8 [报告]
发表于 2007-04-27 14:23 |只看该作者
应验了ypxing 的话,函数调用的时候之所以可以用局部变量指针是因为,在这里被调用函数顺序执行
是阻塞式的,stConnectParam的值一直存在,
而调用pthread_create后test函数直接返回,局部变量的值就不在了!

pthread_join等于是同步该线程,使得在TaskConnect返回之前,stConnectParam的值一直存在,
不过这里使用pthread_join对我没有什么意义(又变成阻塞式),看来要么用全局变量要么动态分配内存了!

谢谢楼上所有的朋友,基本功太差了 -_-
思一克 safedead hellioncu vatdog ypxing
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP