linux epoll 多线程操作的问题

chp845 2014-06-11 06:11:50
最近需要写一个基于EPOLL的服务器,我采用的EPOLL+多线程任务池的处理方式(网络通信的操作主要是I/O操作,以及任务处理,所以,我把上面两个部分放到任务池中处理),但是遇到一个多线程读取socket的问题。我看网络上大部分实现方式,觉得很有问题,网络上多线程读取代码(类似代码如下):
typedef struct _tag_task
{
int fd;
int epollFd;
}TASK;

void* thread_read(void* args)
{
TASK* pTask = (TASK*)args;
char szBuf[256];
read(pTask->fd, szBuf, sizeof(szBuf));
free(pTask);
}

int main(int argc, const char *argv[])
{
int nEpollFd;
int nListenFd;
struct epoll_event ev;

while (true)
{
int nFdNum = epoll_wait(nEpollFd, &ev, 1, -1);
if (nFdNum > 0)
{
if (ev.data.fd == nListenFd)
{
int nFd = accept(nListenFd, 0, 0);
if (nFd == EOF)
{
continue;
}
ev.data.fd = nFd;
ev.events = EPOLLET|EPOLLIN;
epoll_ctl(nEpollFd, EPOLL_CTL_ADD, nFd, &ev);
// epoll_ctl add socket
}
else if (ev.events & EPOLLOUT)
{
pthread_t pid;
TASK* pTask = (TASK*)malloc(sizeof(TASK));
pTask->fd = ev.data.fd;
pTask->epollFd = nEpollFd;
pthread_create(&pid, NULL, thread_read, pTask);
}
}
}

return 0;
}


网络上有很大文章的代码都是采用这样的方式来分发处理I/O操作,但是上面代码会出现一种情况:多个线程不是有可能会同时操作一个Socket(ET模式)?
请问下,各位都是怎么解决类似问题的?
...全文
193 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ztenv 2014-06-13
  • 打赏
  • 举报
回复
引用 7 楼 mujiok2003 的回复:
[quote=引用 6 楼 lianshaohua 的回复:] [quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 3 楼 chp845 的回复:] [quote=引用 2 楼 mujiok2003 的回复:]
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
这样只有两种解决方案: 1.每个socket 加锁 2.开多个线程epoll_wait (EPOLLONESHOT) 请教下,有没有高效的方法???[/quote] 一个IO线程+若干工作线程一般足够了。 [/quote] 大部分情况应该是够了,但当socket过多时,数据分发或数据排队可能是问题[/quote] 不要让IO线程执行阻塞操作(比如阻塞读写, 等待锁, 死锁等), 不会有问题,而且也可以适当增加IO线程数。 [/quote] 您说得太对了,所以不仅仅是用几个线程,还要根据自己的业务设计出不同的IO处理方式,
mujiok2003 2014-06-13
  • 打赏
  • 举报
回复
引用 6 楼 lianshaohua 的回复:
[quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 3 楼 chp845 的回复:] [quote=引用 2 楼 mujiok2003 的回复:]
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
这样只有两种解决方案: 1.每个socket 加锁 2.开多个线程epoll_wait (EPOLLONESHOT) 请教下,有没有高效的方法???[/quote] 一个IO线程+若干工作线程一般足够了。 [/quote] 大部分情况应该是够了,但当socket过多时,数据分发或数据排队可能是问题[/quote] 不要让IO线程执行阻塞操作(比如阻塞读写, 等待锁, 死锁等), 不会有问题,而且也可以适当增加IO线程数。
ztenv 2014-06-13
  • 打赏
  • 举报
回复
引用 5 楼 mujiok2003 的回复:
[quote=引用 3 楼 chp845 的回复:] [quote=引用 2 楼 mujiok2003 的回复:]
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
这样只有两种解决方案: 1.每个socket 加锁 2.开多个线程epoll_wait (EPOLLONESHOT) 请教下,有没有高效的方法???[/quote] 一个IO线程+若干工作线程一般足够了。 [/quote] 大部分情况应该是够了,但当socket过多时,数据分发或数据排队可能是问题
ztenv 2014-06-12
  • 打赏
  • 举报
回复
绝对会出现这种情况,有可能会避免,只是我的方法不一定适用于你;等高手出现
chp845 2014-06-12
  • 打赏
  • 举报
回复
引用 2 楼 mujiok2003 的回复:
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
这样只有两种解决方案: 1.每个socket 加锁 2.开多个线程epoll_wait (EPOLLONESHOT) 请教下,有没有高效的方法???
mujiok2003 2014-06-12
  • 打赏
  • 举报
回复
引用 3 楼 chp845 的回复:
[quote=引用 2 楼 mujiok2003 的回复:]
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
这样只有两种解决方案: 1.每个socket 加锁 2.开多个线程epoll_wait (EPOLLONESHOT) 请教下,有没有高效的方法???[/quote] 一个IO线程+若干工作线程一般足够了。
mujiok2003 2014-06-11
  • 打赏
  • 举报
回复
引用
但是遇到一个多线程读取socket的问题
避免这种情况。 一个fd/socket在一个线程中处理, 不要跨线程, 这样事情将简单的多。
chp845 2014-06-11
  • 打赏
  • 举报
回复
有没有高手可以指导一下呀!

64,281

社区成员

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

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