原本的设计方案:
这个函数在被调用之后,会向我自管理的消息队列(这里记为msg_queue)投递一个专属的消息。随后,调用线程要进入一个等待状态。当另一个处理消息队列的循环过程在检查到这个消息满足条件时,会触发响应的处理,完成以后需要唤醒调用线程,使其继续执行下去。
问题:如何控制这个函数,使其按需要挂起、唤醒调用它的线程。
我目前的设计:
如下代码所示
void func()
{
HANDLE hEvent = CreateEvent();
my_SendMessage(); //----这个函数会将hEvent的引用内容放入消息队列里
WaitForSingleObject(hEvent,....);
........
CloseHandle(hEvent);
}
然后,消息队列处理之后,会在那边SetEvent(hEvent);
我的问题:
这个函数有可能被频繁调用。有没有办法,可以不要每次调用都来一个新的信号量的创建-销毁过程。毕竟是创建内核对象。而且感觉也很不优雅。
我想的另一个替代办法是维持一个全局的 线程-信号量关联表。这样每次调用func后,获取当前的线程ID,然后查询,该线程是否已经设置了我需要的信号量,如果有,则继续使用,无的话,创建。线程退出的时候销毁。不过,这个方案的开销搞不好更多。
麻烦各位朋友给予建议。谢谢。
7 个解决方案
#1
直接等待event就可以了啊
#2
可不可以换个思考角度:为外界提供一个等待一个或者多个事件的函数,这里记为 void func(……);如果事先定义的这些事件没有发生函数就进入阻塞等待状态,直到其他线程把这些事件都准备好了,那么这个阻塞的线程就自然苏醒过来了,这样就省去你的个消息队列了,而只要事先把需要用到的事件定义好就可以了。
#3
WaitForSingleEvent/SetEvent
通过Event来进行同步
通过Event来进行同步
#4
两个方案
第一种,既然是频繁调用的函数,你就为每个调用线程固定创建一个Event就行,不用每次临时创建并Close
可以考虑将句柄放在TLS里
第二种,调用线程投递消息后,自我挂起SuspendThread,然后由处理线程完成后调用ResumeThread 唤醒
第一种,既然是频繁调用的函数,你就为每个调用线程固定创建一个Event就行,不用每次临时创建并Close
可以考虑将句柄放在TLS里
第二种,调用线程投递消息后,自我挂起SuspendThread,然后由处理线程完成后调用ResumeThread 唤醒
#5
这几天把代码写完了,测试效果不错。
看了一下,采用了和您的建议差不多的办法,唯一的区别是我把这个event和资源绑定在了一起,
也就是,把event设置在了连接的数据队列里,这样每次调用func的时候,如果存在资源,则直接处理,如果不存在资源,则自行挂起,等待另一端线程唤醒。而另一端的线程只要有资源投递的动作,就自动设置event。
那么问题解决了。抱歉,我现在看了一下我的帖子,感觉没有完全表述清楚我当初的用意,可能当时没有想到合适的策略。
#6
您的这个建议有点像 nginx的设计呢~
#7
是的没错,当初考虑的只是如何在代码的哪一部分合理的设置event的位置。
#1
直接等待event就可以了啊
#2
可不可以换个思考角度:为外界提供一个等待一个或者多个事件的函数,这里记为 void func(……);如果事先定义的这些事件没有发生函数就进入阻塞等待状态,直到其他线程把这些事件都准备好了,那么这个阻塞的线程就自然苏醒过来了,这样就省去你的个消息队列了,而只要事先把需要用到的事件定义好就可以了。
#3
WaitForSingleEvent/SetEvent
通过Event来进行同步
通过Event来进行同步
#4
两个方案
第一种,既然是频繁调用的函数,你就为每个调用线程固定创建一个Event就行,不用每次临时创建并Close
可以考虑将句柄放在TLS里
第二种,调用线程投递消息后,自我挂起SuspendThread,然后由处理线程完成后调用ResumeThread 唤醒
第一种,既然是频繁调用的函数,你就为每个调用线程固定创建一个Event就行,不用每次临时创建并Close
可以考虑将句柄放在TLS里
第二种,调用线程投递消息后,自我挂起SuspendThread,然后由处理线程完成后调用ResumeThread 唤醒
#5
这几天把代码写完了,测试效果不错。
看了一下,采用了和您的建议差不多的办法,唯一的区别是我把这个event和资源绑定在了一起,
也就是,把event设置在了连接的数据队列里,这样每次调用func的时候,如果存在资源,则直接处理,如果不存在资源,则自行挂起,等待另一端线程唤醒。而另一端的线程只要有资源投递的动作,就自动设置event。
那么问题解决了。抱歉,我现在看了一下我的帖子,感觉没有完全表述清楚我当初的用意,可能当时没有想到合适的策略。
#6
您的这个建议有点像 nginx的设计呢~
#7
是的没错,当初考虑的只是如何在代码的哪一部分合理的设置event的位置。