【问题标题】:how to send std::string in MPI?如何在 MPI 中发送 std::string?
【发布时间】:2014-01-27 10:23:00
【问题描述】:

我想通过 MPI 发送一个字符串变量,但我不知道该怎么做! 我的代码在这里:

static string  fourTupX="Hello";

现在我想通过 MPI 发送它:

int l=std::strlen(fourTupX.c_str());
l++;
MPI::COMM_WORLD.Send (&l,1,MPI::INT,1,7);
MPI::COMM_WORLD.Send ( &fourTupX, 1, MPI::CHAR, 1, 1 );

并在另一边接收它:

int l;
 source=0;
 MPI::COMM_WORLD.Recv (&l,1,MPI::INT , source, 7, status1 );
 cout<<l;
 char* myfourTupX=new char[l];
 MPI::COMM_WORLD.Recv (myfourTupX,l,MPI_CHAR , source, 1, status1 );

但是收到之后fourTupx里面什么都没有!!! 有什么问题?

【问题讨论】:

标签: c++ string mpi


【解决方案1】:

您必须发送从c_str() 获得的字符串缓冲区的内容。您不必先发送字符串长度,因为接收方可以简单地先探查消息,然后分配适当大小的缓冲区:

// Sender

string bla = "blabla";
MPI::COMM_WORLD.Send(bla.c_str(), bla.length(), MPI::CHAR, dest, 1);

// Receiver

MPI::Status status;
MPI::COMM_WORLD.Probe(source, 1, status);
int l = status.Get_count(MPI::CHAR);
char *buf = new char[l];
MPI::COMM_WORLD.Recv(buf, l, MPI::CHAR, source, 1, status);
string bla1(buf, l);
delete [] buf;

这里,接收者使用Probe 来探测匹配的消息并检查status 对象以找出消息中有多少个字符。然后它分配一个相同大小的缓冲区,接收消息并从中构造一个std::string 对象。

【讨论】:

  • 谢谢,我想在 MPICH2 中发送一个带有发送命令的链接列表,有什么办法吗?
  • MPI 无法做到开箱即用。您应该查看Boost.MPI 或类似的包装库,它可以自动(反)序列化 C++ 容器类。此外,MPI-2.2 中已弃用 MPI C++ 绑定,并从最新的 MPI-3.0 标准中完全删除。
  • std::basic_string::c_str() 和 std::basic_string::data() 返回 const char* 导致无效转换的原因。那样安全吗?
  • @fachexot,根据 MPI 标准,MPI_Send 不会修改缓冲区的内容。在 MPI-3.0 中,该参数已被给予 const 处理(并且 MPI-3.0 中也不存在 C++ 绑定)
  • @HristoIliev MPI_Send(bla.c_str(), bla.length(), MPI_CHAR, source, tag, MPI_COMM_WORLD);给出编译器错误,告诉 const char* 的第一个参数类型与参数 void* 不兼容。我该如何解决?
【解决方案2】:

据我了解,您要从 string 对象的开头发送 1 个字符,即 1 个字节。您需要发送整个内容。

发送对象时,需要注意对象内部的指针,可能发送的是指针地址,而不是内容本身。如果 string 对象将实际的 char 数组存储在堆中,则可能就是这种情况。

在这种情况下,我宁愿发送 c_str() 而不是对象本身,并且大小将是 c_str() 的长度加上 1 以在末尾包含空字符。然后你可以在接收到string对象后从字符数组中重构它。

编辑 修改你的字符串发送:

MPI::COMM_WORLD.Send ( fourTupX.c_str(), l, MPI::CHAR, 1, 1 ); //it's l, not 1

那么它应该可以工作了。

【讨论】:

  • 感谢您的检查:)
  • 谢谢,但是当我这样做时,我会得到正确答案和一些有趣字符,我把我编辑的代码放在上面,我不知道是什么有问题吗?
  • 我的输出是这样的:你好═²²²²☺
【解决方案3】:

我知道这是一个很老的问题,但我想分享我的经验,以防其他人碰到这个问题。

看来Hristo的回答已经过时了。为了使其适用于较新版本的 MPI,我建议您使用

// Sender
std::string s = "somestring";
MPI_Send(&s[0],s.size()+1,MPI_CHAR,<destination>,<tag>,MPI_COMM_WORLD);

// Receiver
MPI_Status status;
MPI_Probe(<sender>,<tag>,MPI_COMM_WORLD,&status);
int count;
MPI_Get_count(&status,MPI_CHAR,&count);
char buf [count];
MPI_Recv(&buf,count,MPI_CHAR,<sender>,<tag>,MPI_COMM_WORLD,&status);
std::string s = buf; 

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 2016-11-30
    • 2019-10-06
    • 1970-01-01
    相关资源
    最近更新 更多