0

我想编写一个简单的 UDP 服务器程序,它使用 recvfrom() 接收每个接收到的数据包的数据包,程序将处理它我的原始源代码如下:

for(;;){
n = recvfrom(sockfd, mesg, 10000, 0 ptr_sockaddr, &len);
process(mesg);
}

但是这样一来,如果process()函数需要的时间有点长,就会影响recvfrom(). 所以我需要创建一个新进程或新线程,

  1. 哪个更适合这种情况?线程还是进程?为什么?
  2. 如何处理进程间或线程间通信,我的意思是我需要将字符串mesg传递给新进程(或线程)。如果数据包接收比处理快得多,我应该使用什么样的缓冲方法?

如果能提供一些源代码片段就更好了!

谢谢!

4

5 回答 5

1

我建议有一个循环的线程recvfrom。当它接收到一个数据报时,让它将该数据报放在一个队列中。然后,您可以拥有一个线程池,从队列中提取数据报并对其进行处理。

通常的解决方案是拥有一个互斥锁和一个保护队列的条件变量。将项目添加到队列中的工作方式如下:

  1. 获取互斥锁。

  2. 将项目添加到队列中。

  3. 给条件变量发信号。

  4. 释放互斥锁。

池中的线程这样做:

  1. 获取互斥锁。

  2. 如果队列中有项目,请跳至步骤 5。

  3. 阻止释放互斥锁的条件变量。

  4. 转到第 2 步。

  5. 从队列中删除项目。

  6. 释放互斥锁。

  7. 处理我们从队列中删除的项目。

  8. 转到步骤 1。

不过,您可能希望防止队列无限增长。接收数据报的速度总是可能比处理它们的速度更快,并且让队列的内存使用量不断增长并不是一个好主意。

于 2013-03-27T16:45:44.963 回答
0

过程。然后一个编程错误会破坏一个连接,而不是整个服务器。

对于通信,您可以在父进程和所有子进程之间的 fork() 之前建立一个共享内存区域并同步。使用互斥体/信号量。

于 2013-03-30T13:56:10.100 回答
0

使用线程更简单,因为线程可以看到其父进程的内存。因此它可以访问变量和内存,读取它们并更改它们。

使用进程将不允许您直接访问父进程内存,您必须使用其他方式更改父进程的变量和内存,如共享内存(mmap)

于 2013-03-27T16:45:40.673 回答
0

声明一些结构来包含数据。马洛克一个。在消息中阅读。将 *struct 排队并立即 malloc(或 depool),另一个用于下一条消息。在消费者处理后释放或重新池化 *struct。

您可以通过以下任一方式进行流量控制:

1) 使用有界阻塞队列,处理后释放消费者端的*struct。

2) 使用两个无界阻塞队列 - 一个预填充 *struct 作为池,另一个用于线程之间的通信。当 recvFrom 线程需要一个 *struct 时,将其从池中弹出。当消费者处理完一个 *struct 后,将其推回池中。

于 2013-03-27T16:53:44.913 回答
0

如果函数 process() 没有向父级返回任何内容,则为每条消息创建一个进程要容易得多。您需要做的就是添加 if (fork()<=0) return; 在 process() 的开头,您无需担心覆盖 mesg 和 ptr_sockaddr。

于 2013-03-30T12:13:51.697 回答