伙计们!
我正在* nix下的c上开发多线程服务器 . 在进程的主线程中,我有监听套接字等待连接(接受) . 当它获得连接(accept返回客户端套接字描述符)时,我启动一个新的pthread和一些例程,它回应请求并关闭客户端套接字描述符 . 它看起来像这样:
while(1)
{
sock_cl =(int *)malloc(sizeof(int));
*sock_cl = accept(sock_serv, NULL, NULL);
pthread_create(thread, attr, answer, sock_cl);
}
回答功能:
void *answer(void *arg)
{
int sock_cl;
char *buf;
ssize_t r;
lsres_t *ans;
char *path;
char status[STATUS_SIZE];
sock_cl = *((int *)arg);
if((buf = (char *)malloc(BUF_SIZE + 1)) == NULL)
{
sprintf(status, "%i\n", -1);
send_data(sock_cl, status, STATUS_SIZE);
close(sock_cl);
free(arg);
return NULL;
}
memset(buf, '\0', BUF_SIZE + 1);
if((r = recv(sock_cl, buf, BUF_SIZE, 0)) <= 0)
{
close(sock_cl);
free(arg);
return NULL;
}
path = strtok(buf, "\r\0");
if((ans = lscreate()) == NULL)
{
sprintf(status, "%i\n", -1);
send_data(sock_cl, status, STATUS_SIZE);
}
else
{
if(myls(path, ans) != 0)
{
sprintf(status, "%i\n", -1);
send_data(sock_cl, status, STATUS_SIZE);
}
else
{
sprintf(status, "%i\n", ans->status);
send_data(sock_cl, status, STATUS_SIZE);
send_data(sock_cl, ans->buf, ans->written_size);
}
lsdestroy(ans);
}
close(sock_cl);
free(arg);
return NULL;
}
在回答函数中,我调用recv从客户端重新获取数据并发送一些答案 . 它在Linux系统(Arch,Debian,Ubuntu)下工作正常,但是当我尝试在Unix(Solaris)下运行它时,我在recv函数中得到了分段 . 问题不在缓冲区,因为如果我尝试在与答案功能相同的线程中调用答案功能,我没有分段掉落 . 因此使用带有pthread的套接字存在一些问题 .
请告诉我如何在多线程服务器中使用套接字的任何解决方案 . 谢谢你的未来答案!
3 回答
我认为在unix recv函数失败,分段问题是由于代码段
free(args);
可能是这可能是原因
这个sock_cl在线程之间共享,因为答案函数没有同步,并且因为你释放了这个指针,其他线程也会崩溃,如果可能的话,你可以通过在valgrind中运行来检查同一个程序是否有损坏 .
在Solaris上,通常需要使用
-mt
进行编译才能正确编译和链接多线程程序 . 如果你没有像你看到的那样在线程中随机崩溃 .