每个线程传递一个局部变量会影响到其他线程的变量值?百思不得其解

eziowayne 2014-05-22 04:58:43
计划做一个多线程的TCP服务器,初步进行一些疑问的验证,现在碰到一个想了很久没想通的问题!

思路很简单,为每个接入的socket开辟一个线程,然后进行收发消息:
server端部分代码
        while (1) 
{
int client_sockd = 0;
if ((client_sockd=accept(server_sockd, (SKADDR *) &client_addr,
&sock_len)) < 0)
{
perror("accept error ");
close(client_sockd);
sleep(10);
continue ;
}

printf("[%d]CIP:[%s],PORT[%d]\n", ++count, inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));

// 给消息结构体赋值,从这里启动消息处理线程
pthread_t tid;
RMSG rmsg;
memset(&rmsg, 0, sizeof (rmsg));
rmsg.cli_sockd = client_sockd;
memcpy(&(rmsg.cli_addr), &client_addr, sizeof (client_addr));

pthread_create(&tid, NULL, server_handle, (void *) &rmsg);
}

rmsg是一个消息结构体,包含了一个socket、客户端地址、消息(消息暂时没用到)

然后进入线程,死循环读数据,客户端关闭连接以后线程就会退出。
thread部分代码

void *server_handle(void *args)
{
RMSG *rmsg = (RMSG *) args;
unsigned long tid = pthread_self();
printf("TID[%lu] : SOCK[%d], CIP[%s], PORT[%d]\n", \
tid, \
rmsg->cli_sockd, \
inet_ntoa(rmsg->cli_addr.sin_addr), \
ntohs(rmsg->cli_addr.sin_port));

while(1)
{
char buf[BUFFER_SIZE] = "";
if (recv(rmsg->cli_sockd, buf, BUFFER_SIZE, 0) <= 0)
{
perror("recv error/socket closed ");
break;
}
printf("TID[%lu] : MESSAGE[%s]\n", tid, buf);
}
close(rmsg->cli_sockd);
printf("SOCK[%d] closed....\n", rmsg->cli_sockd); // <-- 这里出问题了。。打印出来的sock是一样的。而且是最后一个连接客户端的socket值
return NULL;
}


脚本运行了10个客户端流水执行(不等上一个退出),每个客户端发送若干条消息,然后线程打印出来的消息和我预期的不一样:
close(rmsg->cli_sockd);
printf("SOCK[%d] closed....\n", rmsg->cli_sockd); // <-- 这里出问题了。。打印出来的sock是一样的。而且是最后一个连接客户端的socket值

print出来的rmsg->cli_sockd是一样的,而且都是最后连进来的客户端的socket。
所以接收消息的时候会打印套接字已经被关闭的情况,这些线程就被动退出了。


这里理论上是一个rmsg对应一个线程的,但是为什么最后rmsg的值被其他线程影响到了,希望高手出现帮我解决一下!

对于代码有什么不清楚的地方请及时提出来,我会立即补充。再次感谢!
...全文
240 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
eziowayne 2014-05-22
  • 打赏
  • 举报
回复
这样的话传递给线程的最好是全局变量或者动态分配的,已经结贴了。谢谢!
eziowayne 2014-05-22
  • 打赏
  • 举报
回复
犯了这么傻的错误,谢谢各位了
TheNewIpad 2014-05-22
  • 打赏
  • 举报
回复
引用 5 楼 TheNewIpad 的回复:
RMSG rmsg; 是一个局部变量。 由于在启动函数中,所以地址是不变的。 会被最后接收的变量覆盖。
第一块代码的第18行。 改为在堆上分配RMSG吧。
lin5161678 2014-05-22
  • 打赏
  • 举报
回复
rmsg是一个局部变量 你的循环执行一次完成之后 对象笑话内存释放 &rmsg变成野指针 传入线程的指针是野指针 于是 出现这些问题
TheNewIpad 2014-05-22
  • 打赏
  • 举报
回复
RMSG rmsg; 是一个局部变量。 由于在启动函数中,所以地址是不变的。 会被最后接收的变量覆盖。
eziowayne 2014-05-22
  • 打赏
  • 举报
回复
引用 2 楼 shenchenman 的回复:
理论上是一个rmsg对应一个线程的。 你说下怎么对应的
补充一下啊,每个客户端发送了不同数目的唯一消息,线程一开是都能接收到的,但有线程退出以后似乎就“影响”了其他的线程!
eziowayne 2014-05-22
  • 打赏
  • 举报
回复
引用 2 楼 shenchenman 的回复:
理论上是一个rmsg对应一个线程的。 你说下怎么对应的
RMSG rmsg; memset(&rmsg, 0, sizeof (rmsg)); rmsg.cli_sockd = client_sockd; memcpy(&(rmsg.cli_addr), &client_addr, sizeof (client_addr)); pthread_create(&tid, NULL, server_handle, (void *) &rmsg); 应该是对应的吧。。想不通怎么搞串了。
shenchenman 2014-05-22
  • 打赏
  • 举报
回复
理论上是一个rmsg对应一个线程的。 你说下怎么对应的
eziowayne 2014-05-22
  • 打赏
  • 举报
回复
希望有人能够帮助我一下!

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧