关于多生产者-单消费者有关问题
关于多生产者-单消费者问题
要实现功能:对一个网络端口的监听,收到数据后解析->解析完成->发送指令给客户端。我的思路是:
收到数据存入队列消费者监听队列读取数据处理。
有没有不使用队列的能实现功能的方法?用XML文件做为数据共享能行?
------解决思路----------------------
不管什么格式文件,都是通过数据流传输过来,你接收到数据,先放到内存列表,后台有现成逐个处理,这样避免阻塞主线程
------解决思路----------------------
如果收到消息之后需要持久化保存,那么你可以考虑一个所谓“队列”的数据结构。
但是如果是很快地(比如说平均只有十几毫秒的)以多线程方式处理掉信息,那么不要画蛇添足地弄什么“队列”。因为.net得系统线程池本身就是一个队列(而且可以自动根据操作系统情况进行优化)。
比如说我们收到一个消息
这里用一句话就把消息放入队列,并且注册了一个并发处理方法,系统线程池随后就会根据操作系统忙闲情况而动态分配线程来执行它。
如果你在“解析并处理”过程中有一部分代码需要“线程同步”,例如即使有100个线程并发执行,我们也希望在某段“管理线程”中所有线程都排队执行——只有一个线程能够执行,那么就使用普通的lock语句。例如
这里在1和2部分都是并发的(例如可能有100个线程都在并发执行),但是在中间 lock{} 中的部分就会让所有相关线程“排队、顺序”执行(同一时间只有1个线程执行此部分)。
这其实是很普通的多线程编程知识。
而java程序员中喜欢纠结的什么“生产者-消费者模式”,在大多数时候,是冗余、繁琐、极容易写成外行代码的那种编程写法。
------解决思路----------------------
持久化存储,可以使用比较轻便的本地嵌入式数据库。
这部分内容其实就跟什么“生产者-消费者模式”没有直接的关系(不要什么都胡乱套用雷人的设计模式名词儿)。
当你开启一个任务的时候,就可以把它保存到数据库中,然后执行完毕则注销。例如
这是很简单的数据库表编程知识(或者如果非要叫做“模式”也随便),就是干一件事之前先记账,干完之后销账。这样在你的系统再次重启动时,就可以先去找找看有没有未销账的任务了。
------解决思路----------------------
嗯,上面的示例代码中的xml变量有并发线程冲突(幻像数据),修改一下
------解决思路----------------------
防止数据丢失,可以制定一个持久化数据机制,定时或每次操作保存数据
要实现功能:对一个网络端口的监听,收到数据后解析->解析完成->发送指令给客户端。我的思路是:
收到数据存入队列消费者监听队列读取数据处理。
有没有不使用队列的能实现功能的方法?用XML文件做为数据共享能行?
------解决思路----------------------
不管什么格式文件,都是通过数据流传输过来,你接收到数据,先放到内存列表,后台有现成逐个处理,这样避免阻塞主线程
------解决思路----------------------
如果收到消息之后需要持久化保存,那么你可以考虑一个所谓“队列”的数据结构。
但是如果是很快地(比如说平均只有十几毫秒的)以多线程方式处理掉信息,那么不要画蛇添足地弄什么“队列”。因为.net得系统线程池本身就是一个队列(而且可以自动根据操作系统情况进行优化)。
比如说我们收到一个消息
string xml = 接受到消息并且以这个变量引用消息;
ThreadPool.QueueUserWorkItem(h => 解析并且处理(xml));
这里用一句话就把消息放入队列,并且注册了一个并发处理方法,系统线程池随后就会根据操作系统忙闲情况而动态分配线程来执行它。
如果你在“解析并处理”过程中有一部分代码需要“线程同步”,例如即使有100个线程并发执行,我们也希望在某段“管理线程”中所有线程都排队执行——只有一个线程能够执行,那么就使用普通的lock语句。例如
private static object flag = new object();
public void 解析并且处理(string xml)
{
//....... 1
lock (flag)
{
//...........受管理的线程部分
}
//....... 2
}
这里在1和2部分都是并发的(例如可能有100个线程都在并发执行),但是在中间 lock{} 中的部分就会让所有相关线程“排队、顺序”执行(同一时间只有1个线程执行此部分)。
这其实是很普通的多线程编程知识。
而java程序员中喜欢纠结的什么“生产者-消费者模式”,在大多数时候,是冗余、繁琐、极容易写成外行代码的那种编程写法。
------解决思路----------------------
持久化存储,可以使用比较轻便的本地嵌入式数据库。
这部分内容其实就跟什么“生产者-消费者模式”没有直接的关系(不要什么都胡乱套用雷人的设计模式名词儿)。
当你开启一个任务的时候,就可以把它保存到数据库中,然后执行完毕则注销。例如
foreach (string xml in 待处理数据列表)
{
ThreadPool.QueueUserWorkItem(h =>
{
var id = Guid.NewGuid().ToString(); //随机分配一个唯一的任务编号
保存到数据库(id, xml);
解析并且处理(xml);
从数据库注销(id);
});
}
这是很简单的数据库表编程知识(或者如果非要叫做“模式”也随便),就是干一件事之前先记账,干完之后销账。这样在你的系统再次重启动时,就可以先去找找看有没有未销账的任务了。
------解决思路----------------------
嗯,上面的示例代码中的xml变量有并发线程冲突(幻像数据),修改一下
foreach (var task in 待处理数据列表)
{
var xml = task;
ThreadPool.QueueUserWorkItem(h =>
{
var id = Guid.NewGuid().ToString(); //随机分配一个唯一的任务编号
保存到数据库(id, xml);
解析并且处理(xml);
从数据库注销(id);
});
}
------解决思路----------------------
防止数据丢失,可以制定一个持久化数据机制,定时或每次操作保存数据