编程之美复习笔记

 

 

1.10 双线程高效下载

伪码给出了典型的生产者消费者问题解答,用一个信号量(semaphore)表示剩余空闲块数(g_seEmpty),一个信号量表示已下载记录数(g_seFull)。

下载线程中消耗空闲块,所以先g_seEmpty.Unsignal(),相当于P(g_seEmpty),完成后g_seFull.Signal(),相当于V(g_seFull)。写磁盘线程则恰好相反,先g_seFull.Unsignal(),相当于P(g_seFull),完成后g_seEmpty.Signal(),相当于V(g_seEmpty)。

值得注意的是Thread的构造函数中指定的是函数指针:Thread(void (*work_func)());这样就可以为不同的线程指定不同的工作函数了。

回顾一下PV操作:

procedure p(var s:samephore);
{
  s.value=s.value-1;
  if (s.value<0) asleep(s.queue);
}
procedure v(var s:samephore);
{
  s.value=s.value+1;
  if (s.value<=0) wakeup(s.queue);
}
与semaphore的机制是一样的,当使用semaphore进行计数时,count==0时将当前的thread阻塞。
后续问题:
1.多个下载线程的实现
TODO
如果直接加入多个下载线程,由于下载完成顺序是不一定的,如何保证访问存储的顺序是有序的?为每一个block加锁?
 
2.windows中有哪些API可以了解用户是否在使用鼠标或者键盘
(1)GetInputState
函数原型: BOOL GetInputState(VOID);
函数功能:该函数确定在当前线程的消息队列中是否有要处理的鼠标,键盘消息.
注意事项:返回值指定是否发生了鼠标,键盘输入.如果检测到输入的话,则返回值为非零值,否则返回值为零

(2)GetLastInputInfo
函数原型:BOOL WINAPI GetLastInputInfo( __out PLASTINPUTINFO plii);
函数功能:获取上次输入操作的时间
参数:[out] 类型:PLASTINPUTINFO结构
一个指向接收到最后一个输入事件时间的LASTINPUTINFO结构指针。
返回值:如果调用函数成功,返回值为非零。
 如果调用函数失败,返回值为零。
说明:调用函数GetLastInputInfo()以后, 结构成员lpi.dwTime 中的值并非上次输入事件发生以后的毫秒数。而是上次输入事件发生时的系统运行时间。相当于上次输入事件发生时执行了lpi.dwTime=::GetTickCount()。::GetTickCount()-lpi.dwTime才是上次输入事件发生以后的毫秒数。
 
比较著名的问题有:生产者消费者问题,读者写者问题,循环队列读写问题,等。
 
 
 
 
 
posted @ 2013-08-30 11:19  Avril  阅读(417)  评论(0编辑  收藏  举报