我正在尝试通过rpc协议获取NFS磁盘配额。通过使用OpenMP,我创建并行udp连接。该程序在1和2核心运行时没有任何错误。当我将核心数增加到4时,经过一段时间的程序在“clntudp_create()”函数中给出“RPC:端口映射器故障 - RPC:无法发送”错误,这就是创建udp连接。我正在使用以下代码来完成这项工作。
/*
* 0 -> True
* 1 -> Couldn't resolve hostname
* 2 -> Udp connection couldn't initiate
* 3 -> Query couldn't run
* 4 -> Unknown error
*/
long long int diskOfUser::getNfsQuota(string blockDevice, int uid)
{
//some address resolving operations
int whereToSplit = blockDevice.find(':');
if(whereToSplit == std::string::npos)
return 5;
std::string host = blockDevice.substr(0, whereToSplit);
std::string path = blockDevice.substr(whereToSplit+1, blockDevice.size() - whereToSplit);
char *pathToGo = new char[path.size()+1];
strcpy(pathToGo,path.c_str());
char *hostToGo = new char[host.size()+1];
strcpy(hostToGo,host.c_str());
//variable definitions
struct getquota_args *gqArgs;
gqArgs = new struct getquota_args;
struct getquota_rslt *gqRslt; //quota result object
gqRslt = new struct getquota_rslt;
struct sockaddr_in server_addr; //udp connection address
struct hostent *hp;
struct timeval timeout, totTimeOut; //timeout values
CLIENT *client = NULL; //udp client
int socket = RPC_ANYSOCK;
timeout.tv_usec = 0;
timeout.tv_sec = 6;
totTimeOut.tv_sec = 25;
totTimeOut.tv_usec = 0;
//try to resolve host
if ((hp = gethostbyname(hostToGo)) == NULL)
{
delete pathToGo;
delete hostToGo;
return 1; //hostname couldn't resolve
}
/* Try to start UDP connection (Problematic part)*/
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(875);
memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_port = 0;
if ((client = clntudp_create(&server_addr, (u_long)100011, (u_long)1, timeout, &socket)) == NULL)
{
delete pathToGo;
delete hostToGo;
clnt_pcreateerror("error"); // gives the following error "RPC: Port mapper failure - RPC: Unable to send"
return 2; //udp connection could not start
}
/* UDP connection created */
//quota asking operations ...
}
有没有办法让这个工作线程安全?
编辑:“RPC:无法发送; errno =错误的文件描述符”clnt_sperror()函数发出此错误。我分别用一个核心启动四个进程,程序运行没有错误。但是4个核心的1个进程总是在爆炸。
解答:
/* UDP connection oluşturuluyor */
if ((client = clnt_create(hostToGo, (u_long)100011, (u_long)1, "UDP")) == NULL)
{
delete pathToGo;
delete hostToGo;
return 2; //rquotad ile udp connection oluşturma işlemi başarısız oldu
}
/* UDP connection oluşturuldu */
client->cl_auth = authunix_create_default(); //rpc authentication handle
gqArgs->gqa_uid = uid; //argumanlar set ediliyor
gqArgs->gqa_pathp = pathToGo;
我用clnt_create()函数达到目标。它是clntudp_create()的线程安全替代品。但是,在服务器端rquota.d将所有请求分开并逐个回答。因此,它没有完全优化。