我想编写一个简单的UDP服务器程序,它使用recvfrom()来接收数据包 对于每个收到的数据包,程序将处理它 我的原始源代码如下:
for(;;){
n = recvfrom(sockfd, mesg, 10000, 0 ptr_sockaddr, &len);
process(mesg);
}
但是这样,如果process()
函数需要很长时间,它会影响recvfrom()
。所以我需要创建一个新进程或新线程,
mesg
传递给新的
进程(或线程)。如果数据包接收速度快得多
处理,我应该使用什么样的缓冲方法?如果可以提供一些源代码片段,那就更好了!
谢谢!
答案 0 :(得分:1)
我建议让一个线程围绕recvfrom
循环。当它收到数据报时,让它将该数据报放在队列中。然后,您可以拥有一个线程池,用于从队列中提取数据报并对其进行处理。
通常的解决方案是使用互斥锁和保护队列的条件变量。将项添加到队列的工作方式如下:
获取互斥锁。
将项目添加到队列中。
发出条件变量信号。
释放互斥锁。
池中的线程执行此操作:
获取互斥锁。
如果队列中有项目,请跳至步骤5.
阻止条件变量释放互斥锁。
转到第2步。
从队列中删除该项目。
释放互斥锁。
处理我们从队列中删除的项目。
转到第1步。
您可能希望阻止队列无限增长。你总是有可能以比处理它们更快的速度接收数据报,并且允许队列的内存使用量继续增长并不是一个好主意。
答案 1 :(得分:0)
使用线程更简单,因为线程可以看到其paraent进程的内存。所以它可以访问变量和内存,读取它们并更改它们。
使用进程将不允许您直接写入父进程内存,您必须使用其他方法来更改父进程的变量和内存,如共享内存(mmap)
答案 2 :(得分:0)
声明一些包含数据的结构。 Malloc一个。阅读一条消息。排队* struct并立即malloc,(或depool),另一个用于下一条消息。在消费者处理后的*结构中的自由或重新组合。
您可以通过以下任一方式进行流量控制:
1)使用有界阻塞队列,在处理后释放消费者端的*结构。
2)使用两个无界阻塞队列 - 一个预先填充* struct作为池,另一个预先填充线程之间的通信。当recvFrom线程需要*结构时,从池中弹出它。当消费者处理了*结构时,将其推回到池中。
答案 3 :(得分:0)
如果函数process()没有向父级返回任何内容,则每条消息创建一个进程要容易得多。你需要做的就是添加if(fork()< = 0)return;在process()的开头,你不必担心覆盖mesg和ptr_sockaddr。
答案 4 :(得分:0)
过程。然后编程错误将拆除单个连接而不是整个服务器。
对于通信,您可以在父和所有子进程之间的fork()之前建立共享内存区域并进行同步。使用互斥锁/信号量。