这是情况.
我有一个经理应用程序将产生一个线程.该线程将连续运行并处理通过USB连接到系统的电路板的串行通信.管理应用程序便于在系统上运行的其他应用程序和此线程之间的通信.线程需要真正执行两件事情:
>通过串行在可变定时器上投票取样数据通常大约每分钟一次(串行总线相当慢,波特率为4800.我无法控制)
>促进与经理申请沟通. (即其他应用程序将请求样本数据,管理员将请求转发给线程,线程执行操作并返回数据)
我的初始设计是一个简单的设计和作品.我使用一个队列和一个互斥为管理器进行线程通信.所以线程的逻辑如下:
>初始化
>虽然我们还没有收到来自经理的关机命令
>如果我们的定时器已经启动,请轮询主板以获取数据
>否则,检查我们是否有一个由管理员发布到队列的消息.如果是这样,处理它
问题是我没有考虑cpu利用率. 99.9%的时间我的线程正在处理任何东西,只是吸取力量.我需要实现一种睡眠方式,直到有工作要做.所以有几个想法:
Use select() to block. This can block based on the timer I need to use,and I could change the queue messaging implementation to socket
messaging. So instead,the thread would open a client socket to the
manager and the manager would pass the messages over the socket to the
thread. Then select() would sleep until there was activity on the fd
or my timer was up.
Pro:完全是我需要的功能.
Con:对于你共享内存的线程来说,这个socket是不是有很大的处理能力呢?
Use a signal system. (Someone more knowledgeable in Linux can pipe up here with an implementation example… I’m not sure exactly how to
do it.) But the thread could sleep for the duration of the timer,and
wake up to process if a signal was received from the manager.
Pro:使用共享内存保持当前的实现
Con:不知道如何实现.有没有像select()这样的函数,而不是使用fds?
Potentially a mutex. I could block until a mutex was posted to by the manager.
Pro:仍然分享内存
Con:可能需要将定时器处理移动到管理器,并且确实不是一个选项,因为它具有其他定时器和执行关键工作.
请推荐并自由批评.我可以接受任何有效的选择.请注意,这是在嵌入式系统上运行,因此资源使用至关重要.
解决方法
#include <stdio.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> static sem_t s_sem; static int iAlive = 1; void* thFunc(void *param) { printf("%s : ENTER \n",__FUNCTION__); while(iAlive) { printf("%s : waiting \n",__FUNCTION__); sem_wait(&s_sem); printf("%s : got a signal - doing something \n",__FUNCTION__); sleep(1); } printf("%s : EXIT \n",__FUNCTION__); return 0; } int main() { pthread_t thread; sem_init(&s_sem,0); if(0 != pthread_create(&thread,NULL,thFunc,NULL)) { printf("%s : pthread_create Failed \n",__FUNCTION__); return -1; } while ( getchar() != 'q' ) { printf("%s : sending signal \n",__FUNCTION__); sem_post(&s_sem); } iAlive = 0; sem_post(&s_sem); pthread_join(thread,NULL); sem_destroy(&s_sem); return 0; }
如果需要超时,可以使用sem_timedwait替换sem_wait.