Chinaunix首页 | 论坛 | 博客
  • 博客访问: 701556
  • 博文数量: 102
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1748
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-23 15:42
个人简介

寻找严肃、沉默和专注的力量。

文章分类

全部博文(102)

文章存档

2015年(26)

2014年(8)

2013年(68)

分类: C/C++

2013-07-13 11:01:08

    信号无需由同一个线程来获取和释放,因此信号可用于异步事件通知,如用于信号处理程序中。同时,由于信号包含状态,因此可以异步方式使用,而不用象条件变量那样要求获取互斥锁。但是,信号的效率不如互斥锁高。缺省情况下,如果有多个线程正在等待信号,则解除阻塞的顺序是不确定的。信号在使用前必须先初始化,但是信号没有属性。计数信号量与互斥锁一起使用时的功能几乎与条件变量一样强大。在许多情况下,使用计数信号量实现的代码比使用条件变量实现的代码更为简单。本文参考:1、Linux多线程编程-信号量的使用2、Linux C++ 一个线程池的简单实现
CThread.h

  1. #ifndef CTHREAD_H_
  2. #define CTHREAD_H_

  3. #include <pthread.h>

  4. class CThread {
  5. private:
  6.     pthread_t m_thread; //保持线程句柄
  7. public:
  8.     CThread(void* (*threadFuction)(void*),void* threadArgv);
  9.     virtual ~CThread();

  10.     void JoinThread();
  11. };

  12. #endif /* CTHREAD_H_ */

CThread.cpp

  1. #include "CThread.h"

  2. CThread::CThread(void* (*threadFuction)(void*),void* threadArgv) {

  3.     // 初始化线程属性
  4.     pthread_attr_t threadAttr;
  5.     pthread_attr_init(&threadAttr);

  6.     pthread_create(&m_thread, &threadAttr, threadFuction, threadArgv);
  7. }

  8. CThread::~CThread() {
  9.     // TODO Auto-generated destructor stub
  10. }


  11. void CThread::JoinThread()
  12. {
  13.     // join
  14.     pthread_join(m_thread, NULL);
  15. }

CThreadManager.h

点击(此处)折叠或打开

  1. #ifndef CTHREADMANAGER_H_
  2. #define CTHREADMANAGER_H_

  3. #include <stdio.h>
  4. #include <list>
  5. #include <queue>
  6. #include <semaphore.h>

  7. #include "CThread.h"

  8. using namespace std;

  9. class CThreadManager {
  10.     friend void* ManageFuction(void*);
  11. private:
  12.     sem_t m_sem;    // 信号量
  13.     pthread_mutex_t m_mutex; // 互斥锁

  14.     queue<int> m_queWork; // 工作队列
  15.     list<CThread*> m_lstThread; // 线程list

  16.     int (*m_threadFuction)(int); //函数指针,指向main函数传过来的线程执行函数


  17. public:
  18.     CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt);
  19.     virtual ~CThreadManager();

  20.     int WaitSem();

  21.     int PostSem();

  22.     int LockMutex();

  23.     int UnlockMutex();

  24.     void PushWorkQue(int nWork);

  25.     int PopWorkQue();

  26.     int RunThreadFunction(int nWork);
  27. };

  28. #endif /* CTHREADMANAGER_H_ */


CThreadManager.cpp

点击(此处)折叠或打开

  1. #include "CThreadManager.h"

  2. // 线程执行函数,它只是个壳子,处理信号量和互斥锁等,
  3. // 最后调用main函数传过来的线程执行函数来实现业务处理
  4. void* ManageFuction(void* argv)
  5. {
  6.     CThreadManager* pManager = (CThreadManager*)argv;

  7.     // 进行无限循环(意味着线程是不销毁的,重复利用)
  8.     while(true)
  9.     {
  10.         // 线程开启后,就在这里阻塞着,直到main函数设置了信号量
  11.         pManager->WaitSem();
  12.         printf("thread wakeup.\n");

  13.         // 从工作队列中取出要处理的数
  14.         pManager->LockMutex();
  15.         int nWork = pManager->PopWorkQue();
  16.         pManager->UnlockMutex();

  17.         printf("call Count function.\n");
  18.         pManager->RunThreadFunction(nWork);
  19.     }

  20.     return 0;
  21. }


  22. CThreadManager::CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt) {

  23.     sem_init(&m_sem, 0, 0);
  24.     pthread_mutex_init(&m_mutex, NULL);

  25.     m_threadFuction = threadFuction;

  26.     for(int i=0; i<nMaxThreadCnt; i++)
  27.     {
  28.         CThread* pThread = new CThread(ManageFuction, this);
  29.         printf("thread started.\n");
  30.         m_lstThread.push_back(pThread);
  31.     }
  32. }

  33. CThreadManager::~CThreadManager()
  34. {
  35.     sem_destroy(&m_sem);
  36.     pthread_mutex_destroy(&m_mutex);

  37.     list<CThread*>::iterator it;
  38.     for(it=m_lstThread.begin(); it!=m_lstThread.end();it++)
  39.     {
  40.         (*it)->JoinThread();
  41.     }
  42. }

  43. // 等待信号量
  44. int CThreadManager::WaitSem()
  45. {
  46.     return sem_wait(&m_sem);
  47. }

  48. // 设置信号量
  49. int CThreadManager::PostSem()
  50. {
  51.     return sem_post(&m_sem);
  52. }

  53. // 取得锁
  54. int CThreadManager::LockMutex()
  55. {
  56.     int n= pthread_mutex_lock(&m_mutex);
  57.     return n;
  58. }

  59. // 释放锁
  60. int CThreadManager::UnlockMutex()
  61. {
  62.     return pthread_mutex_unlock(&m_mutex);
  63. }

  64. // 往工作队列里放要处理的数
  65. void CThreadManager::PushWorkQue(int nWork)
  66. {
  67.     m_queWork.push(nWork);
  68. }

  69. // 从工作队列中取出要处理的数
  70. int CThreadManager::PopWorkQue()
  71. {
  72.     int nWork = m_queWork.front();
  73.     m_queWork.pop();

  74.     return nWork;
  75. }

  76. // 执行main函数传过来的线程执行函数
  77. int CThreadManager::RunThreadFunction(int nWork)
  78. {
  79.     return (*m_threadFuction)(nWork);
  80. }



ThreadTest.cpp

  1. #include <stdio.h>
  2. #include <unistd.h>

  3. #include "CThreadManager.h"

  4. using namespace std;

  5. // 线程要执行的函数
  6. int Count(int nWork)
  7. {
  8.     int nResult = nWork * nWork;
  9.     printf("count result is %d\n",nResult);

  10.     return 0;
  11. }

  12. int main() {

  13.     // 创建线程管理类的实例,把要执行的线程函数和最大线程数传进去
  14.     CThreadManager* pManager = new CThreadManager(Count, 3);

  15.     // 把要进行计算的数放到工作队列中
  16.     pManager->PushWorkQue(5);
  17.     pManager->PushWorkQue(20);

  18.     // 设置信号量,唤醒线程
  19.     pManager->PostSem();
  20.     pManager->PostSem();

  21.     // 等待子线程执行
  22.     sleep(1);

  23.     return 0;
  24. }



阅读(2207) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~