在进程和线程之间进行选择,以及进程间(线程)通信

时间:2013-03-27 16:37:01

标签: c linux multithreading process network-programming

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

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

但是这样,如果process()函数需要很长时间,它会影响recvfrom()。所以我需要创建一个新进程或新线程,

  1. 哪一个更适合这种情况?线程还是进程?为什么呢?
  2. 如何处理进程间或线程间的通信,我 意味着我需要将字符串mesg传递给新的 进程(或线程)。如果数据包接收速度快得多 处理,我应该使用什么样的缓冲方法?
  3. 如果可以提供一些源代码片段,那就更好了!

    谢谢!

5 个答案:

答案 0 :(得分:1)

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

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

  1. 获取互斥锁。

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

  3. 发出条件变量信号。

  4. 释放互斥锁。

  5. 池中的线程执行此操作:

    1. 获取互斥锁。

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

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

    4. 转到第2步。

    5. 从队列中删除该项目。

    6. 释放互斥锁。

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

    8. 转到第1步。

    9. 您可能希望阻止队列无限增长。你总是有可能以比处理它们更快的速度接收数据报,并且允许队列的内存使用量继续增长并不是一个好主意。

答案 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()之前建立共享内存区域并进行同步。使用互斥锁/信号量。