STL中map的小问题 郁闷。。。找了两天没找到原因~~~

rwjlqn 2009-05-11 10:57:30
STL中map的小问题 郁闷。。。找了两天没找到原因~~~
服务端运行后先创建一个线程(此线程专门负责把map中的数据发送出去的)。 然后就进入main主线程里面 等待客户端telnet上来 客户端telnet上来后就再创建一个线程用于专门接受telnet上来的数据,此线程调用SplitString函数用于分割telnet上来的字符串 在SplitString中把分割后的字符串保存到map里。
问题:两个客户端同时telnet上来后在SplitString中能同时把两条数据保存到map里,可是为何在另一个线程里(send_thread线程)就只能打印出一条数据呢? (要是客户端不同时telnet的话,在send_thread线程里就能全部打印出来)

#define SERVPORT 10000
#define MAXDATASIZE 10
#define HG_LARGE_STR_LEN 500

map<string, string> mapphone;
map<string, string>::iterator iter;

using namespace std;

string SplitString(string receive_data)
{
/* 分割 receive_data
* 分解出 关键字(p_key), 手机号码(phone)和短信内容(phone_note)
* receive_data = "text\t15001040895\tHello world!";
*/
//cout<<"SplitString receive_data: "<<receive_data<<endl;
string arg_phone = "";
string arg_phone_note = "";

char str[1024];
strcpy(str,receive_data.c_str());

const char * split ="\t";
char *p_key1;
p_key1 = strtok (str,split);
string p_key = p_key1;

char * phone;
phone = strtok(NULL,split);

arg_phone = phone;

char *phone_note;
phone_note = strtok(NULL,split);

arg_phone_note = phone_note;

mapphone.insert(pair<string, string>(arg_phone, arg_phone_note));
/* while(1) //在此处.两个客户端同时telnet过来后 能打印出所接收的数据 (此处的代码跟下面的代码是一样一样的啊)
{
if (!mapphone.empty())
{
for (iter = mapphone.begin(); iter != mapphone.end(); iter++)
{
cout<<"phonei: "<<iter->first<<" phone_notei: "<<iter->second<<endl;
string key = iter->first;
if(mapphone.empty())
{
break;
}
mapphone.erase(key);
}
if(mapphone.empty())
{
cout<<"空了"<<endl;
}
}
else
{
sleep(4);
}
}*/

return " ";
}

void *thread(void *data)
{
/* 接受客户端telnet线程
*
* */

pthread_detach (pthread_self ( ));
int *client_fd = (int*)data;
int c_fd = *client_fd;
//cout<<"c_fd: "<<c_fd<<endl;
string receive = "";
int recvbytes;
char buf[1024];
recvbytes = recv(c_fd ,buf ,sizeof(buf) ,0);
buf[recvbytes-2] = '\0' ;
receive = receive + buf;
close(c_fd);

string p_key = SplitString(receive);

pthread_exit(NULL);
}

void *send_thread(void *arg)
{
/* 发送短信线程
*
* */
pthread_detach(pthread_self());

while(1) //在此处.两个客户端同时telnet过来后 不能打印出所接收的数据(这就是问题所在) (客户端要是不是同时telnet过来的 就能打印出客户端发来的数据)
{
if (!mapphone.empty())
{
for (iter = mapphone.begin(); iter != mapphone.end(); iter++)
{
cout<<"phonei: "<<iter->first<<" phone_notei: "<<iter->second<<endl;
string key = iter->first;
if(mapphone.empty())
{
break;
}
mapphone.erase(key);
}
if(mapphone.empty())
{
cout<<"空了"<<endl;
}
}
else
{
sleep(4);
}
}
pthread_exit(NULL);
}

int main(void)
{
/* socket_server端
*
* */
int sockfd;
char buf[1024];
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
) == -1)
sockfd = socket(AF_INET, SOCK_STREAM, 0);

my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr);
listen(sockfd, MAXDATASIZE);
pthread_t id;

if (pthread_create(&id , &id_attr , send_thread, NULL ) < 0 ) //发送短信线程
{
cout<<"pthread_create error"<<endl;
}

while(1)
{

socklen_t sin_size ;
//cout<<"sin_size: "<<sin_size<<endl;
//cout<<"sockfd: "<<sockfd<<endl;
int client_fd;
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
//if ((client_fd = accept(sockfd, NULL, NULL)) == -1)
{
//cout<<"accept出错"<<endl;
perror("accept");
exit(1);
}
//cout<<"received a connection from "<<inet_ntoa(remote_addr.sin_addr)<<endl;

if (pthread_create(&id , &id_attr , thread, (void*)&client_fd ) < 0 )//接受telnet客户端线程
{
cout<<"pthread_create error"<<endl;
}

}
close(sockfd);
cout<<"main over!"<<endl;
}


...全文
145 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
搞定了~~ 谢谢大家
hairetz 又想亲你啦~~
liliangbao 2009-05-11
  • 打赏
  • 举报
回复
帮顶~
  • 打赏
  • 举报
回复
操作可以看这里吧,你都用到分离线程,没道理不了解线程属性啊。
http://docs.sun.com/app/docs/doc/819-7051/6n919hpag?l=zh&a=view
crst_zh 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 taodm 的回复:]
map出错而数组不错的最可能原因就是并发写操作,破坏了map的内部结构。
[/Quote]
果然简明扼要啊:)佩服佩服
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 rwjlqn 的回复:]
引用 8 楼 taodm 的回复:
map出错而数组不错的最可能原因就是并发写操作,破坏了map的内部结构。


不是很理解map的并发写操作 能否大体讲解一番~~ 不胜感激~~
[/Quote]

多线程同时操作公共数据(比如你这个map),最好加锁,可以用互斥锁来保证。
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 taodm 的回复:]
map出错而数组不错的最可能原因就是并发写操作,破坏了map的内部结构。
[/Quote]

不是很理解map的并发写操作 能否大体讲解一番~~ 不胜感激~~
taodm 2009-05-11
  • 打赏
  • 举报
回复
map出错而数组不错的最可能原因就是并发写操作,破坏了map的内部结构。
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 crst_zh 的回复:]
考虑:map是全局的。加入你的 SplitString 正在修改map,在这个过程中的任意时刻,都可能被send_thread中断,这时候对map的任何判断都是不准确的。
[/Quote]

我试试看用用你的想法~~
另外谢谢你~~
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 taodm 的回复:]
如果真怀疑是map的问题的话,就试一下自己用数组实现同样功能,对比一下呗。
[/Quote]

我用数组试了 数组没有问题 可以达到目的的~~~~
crst_zh 2009-05-11
  • 打赏
  • 举报
回复
考虑:map是全局的。加入你的 SplitString 正在修改map,在这个过程中的任意时刻,都可能被send_thread中断,这时候对map的任何判断都是不准确的。
crst_zh 2009-05-11
  • 打赏
  • 举报
回复
你的map没有同步,多线程访问map,你可以制作一个快照供读取,或者就是采用线程间同步,防止map被意外的改变。
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
谢谢 试试看~~~
taodm 2009-05-11
  • 打赏
  • 举报
回复
如果真怀疑是map的问题的话,就试一下自己用数组实现同样功能,对比一下呗。
rwjlqn 2009-05-11
  • 打赏
  • 举报
回复
自己顶起来啊

64,439

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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