Socket通信 是否需要加锁(线程同步)?
我编写了一个作为服务器运行的,极简单的数据转发器,工作流程用伪代码表示如下:intmain(){WSAStartup();创建两个线程;WaitForMultipleOb...
我编写了一个作为服务器运行的,极简单的数据转发器,工作流程用伪代码表示如下:
int main()
{
WSAStartup();
创建两个线程;
WaitForMultipleObjects()等待两个线程自然结束;
return 0;
}
void Thread1()
{
初始化套接字;
绑定端口,开始侦听;
建立TCP连接;
while(1)
{
if(连接正常)
{
接收socket1发来的数据,存放到Buffer1;
从socket2将Buffer1中的数据转发出去;
清空缓冲区;
}
else
break;
}
清理socket等等等等;
}
void Thread2()
{
初始化套接字;
绑定端口,开始侦听;
建立TCP连接;
while(1)
{
if(连接正常)
{
接收socket2发来的数据,存放到Buffer2;
从socket1将Buffer2中的数据转发出去;
清空缓冲区;
}
else
break;
}
清理socket等等等等;
}
现在的问题是,如果在我一个线程正在socket1中接收数据的过程中发生了线程切换(假定共接收1024个Byte,现在接收到第594个的时候发生了Switch Context),然后第二个线程对socket1进行了操作,那么会不会发生程序当掉或者数据混乱的问题?换句话说,我需不需要对While(1)中的操作进行加锁,以确保操作的原子性? 展开
int main()
{
WSAStartup();
创建两个线程;
WaitForMultipleObjects()等待两个线程自然结束;
return 0;
}
void Thread1()
{
初始化套接字;
绑定端口,开始侦听;
建立TCP连接;
while(1)
{
if(连接正常)
{
接收socket1发来的数据,存放到Buffer1;
从socket2将Buffer1中的数据转发出去;
清空缓冲区;
}
else
break;
}
清理socket等等等等;
}
void Thread2()
{
初始化套接字;
绑定端口,开始侦听;
建立TCP连接;
while(1)
{
if(连接正常)
{
接收socket2发来的数据,存放到Buffer2;
从socket1将Buffer2中的数据转发出去;
清空缓冲区;
}
else
break;
}
清理socket等等等等;
}
现在的问题是,如果在我一个线程正在socket1中接收数据的过程中发生了线程切换(假定共接收1024个Byte,现在接收到第594个的时候发生了Switch Context),然后第二个线程对socket1进行了操作,那么会不会发生程序当掉或者数据混乱的问题?换句话说,我需不需要对While(1)中的操作进行加锁,以确保操作的原子性? 展开
2个回答
2011-05-25
展开全部
一般情况下,不会采用这种做法。
对同一个socket用多个线程访问会造成程序逻辑不清楚,而且也会导致其它问题,例如对tcp连接发生的各种事件进行处理也会很麻烦,例如对断开事件和异常的处理。
从你的程序功能来讲,这种简单的转发,完全可以放在同一个线程里面来做。通过select调用来侦测两个socket的事件,然后分别做出相应的处理。
对同一个socket用多个线程访问会造成程序逻辑不清楚,而且也会导致其它问题,例如对tcp连接发生的各种事件进行处理也会很麻烦,例如对断开事件和异常的处理。
从你的程序功能来讲,这种简单的转发,完全可以放在同一个线程里面来做。通过select调用来侦测两个socket的事件,然后分别做出相应的处理。
更多追问追答
追问
你的意思是……直接把功能实现做到主线程里面?而且要使用非阻塞I/O来做?
追答
不清楚 你的主线程干什么的,我只是说这个转发可以放在同一个线程里做。
用BSD Socket API.
做两个缓冲数据结构(例如环),用来缓冲数据
一个循环大概是这样的,由于不清楚你的连接过程,省去了连接建立. 具体用法请看API说明
while(1)
{
清除事件
select 所有socket事件 注意超时参数的选择
{
返回= 0: 没有事件,continue
返回> 0: 有事件
{
判断是哪个socket的什么事件
异常->异常处理
读事件->读取数据, 塞入相应缓冲,根据成功读取数据量调整缓冲的尾指针,注意判断头尾指针的冲突。
如果读到0个,断开。
写事件->从对应缓冲中获取数据,发出,根据send的返回调整缓冲的头指针
}
其它情况:出问题了
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询