c - c - 通过 pthread_create 时套接字失败
问题描述
我有一个接受客户端的服务器。我正在做一些多线程,当我创建一个线程时,我将 socketfd 作为参数传递。接受失败,因为它需要的 sockFd 为零。但是我不知道为什么会这样。sockfd 对 take_client 函数有效,并且已正确设置。我刚刚包含了我的代码的这一部分,因为我确定问题就在这里。
void* thread_func(void* pSockfd) {
int sockFd;
sockFd = *(int*)pSockfd;
printf("sockFD = %d\n", sockFd); //returns zero
struct sockaddr_in sockAddr;
socklen_t sockAddrSize;
sockAddrSize = sizeof(struct sockaddr_in);
accept(sockFd, (struct sockaddr*) &sockAddr, &sockAddrSize);
return 0;
}
void take_client(int sock) { //when called, 'sock' is a valid number > 0
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, (void*)&sock);
}
如果有什么突出的可能是一个问题,我将非常感激听到。谢谢!
解决方案
您的代码中存在竞争条件,“有时”可能看起来不错:
void take_client(int sock) { //sock live on stack here
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, (void*)&sock);
// you pass the stack address of sock to your thread
}
您传递的地址在线程运行时必须保持有效,因此您可以负担得起(它在某处有点“全局”),或者您需要分配一个新缓冲区并将其传递给线程。
有时您会看到代码将 sock 值转换为 void* ( (void*)sock) 并将指针转换回线程中的 int。
这可能有效,但我认为分配一个新缓冲区对可读性更好,并且明确负责该缓冲区的所有权(在线程之间共享“sock”需要锁定才能完全安全)。
此外,通常,您最终需要将更多信息传递给线程,因此已经有一个缓冲区可以简化代码的演变。
推荐阅读
- javascript - 如何使用我编码的 chrome 扩展名更改突出显示文本的颜色?(参考图片)
- python - 为什么序列化 QuerySet 我要获取一个字符串?
- sql - 如何返回出现在由另一个值分组的所有 2 值元组中的所有值?
- c++ - 使用 libssh C++ 包装器的 Windows 路径问题
- javascript - 将脚本从请求更改为 axios - 记录待处理的承诺
- html - 我可以使用链接标签预连接到 WebSocket 目标吗?
- mongodb - 我如何检索一个文档以及其中一个孩子?
- python - 需要正确的方法来加入/合并/连接两个 DataFrame
- minimax - 用两个任务实现 Minimax 算法
- asp.net-core - .net core 3.1 & 身份问题(声称 nameidentifier 的 id 与任何用户都不匹配,而声称名称是正确的)