Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581072
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-05-25 17:58:26

linux posix pthread 中通常会使用到多线程并发运行多个函数实体的情况,osip2 中也提供相同的功能。
大体的流程便是: 声明并实现函数,创建匹配的函数指针,将函数指针指向函数实体,
传入函数指针,传入函数运行需要的参数列表到线程方法中(pthread : thread , osip:osip_create_thread ) , 运行线程。

本文介绍的是如何将 osip2 中线程的创建、运行、空间释放封装到一个类中。
这样在需要使用并发运行多个函数的时候,只需要创建一个类实例,通过该类实例中的成员方法调用便可执行上述的流程。

在这里使用的线程并发方式是 join ,线程的并发方式有: join , detach
简单的举例解释,比如说现有 3 个线程 main 函数,main 函数中另起的两个线程 A , B
join ------->  main 函数会等到 A, B 线程运行结束之后,在终止自己这一主线程
detach----> main 函数的结束不受 A, B线程执行结束所影响

适用场景:
join------>(a = b + c , b = 1+2 , c = 2+3  | main running (a=b+c) , A running (b = 1+2)  , B running (c = 2+3))
这种情况下, main 这一主线程中需要执行计算是需要线程 A 和 线程 B 执行结果的,也就是说有时序性的,并发方式使用 join

detach-----> (a= 1+1 , b= 1+2 , c = 1+3 | main running ( a = 1+1 ) ,A running ( b = 1+2 ) , B running ( c = 1+3 ) )
这种情况下, main ,A ,B 这三个线程所需要执行的计算是互相独立的,没有任何的时序性,并发方式使用 detach 可以将
系统中的并发度增加到最大,可以充分利用系统资源

实例代码如下:


1. my_pipe.h && 2. my_pipe.cpp : linker 


3. ThreadLoader.h

点击(此处)折叠或打开

  1. #ifndef THREAD_BASE_H__
  2. #define THREAD_BASE_H__

  3. #include "my_pipe.h"

  4. class ThreadLoader
  5. {
  6. public :
  7.     void *thread ;
  8.     myPipe wakeup ;
  9. public :
  10.     ThreadLoader () ;
  11.     ~ThreadLoader () ;
  12.     
  13.     int ThreadRelease () ;
  14.     int ThreadStart ( void *(*loader)(void*) , void *arg_list) ;
  15.     int ThreadWakeUp () ;
  16.     
  17.     int ThreadPrintState () ;

  18. } ;

  19. #endif

4. ThreadLoader.cpp

点击(此处)折叠或打开

  1. #ifndef OSIP_MT
  2. #define OSIP_MT
  3. #endif

  4. #include <osip2/osip_mt.h>
  5. #include <osip2/osip_condv.h>
  6. #include <osip2/osip.h>
  7. #include <osipparser2/osip_port.h>

  8. #include <stdio.h>
  9. #include <stdlib.h>

  10. #include "ThreadLoader.h"
  11. #include "my_pipe.h"

  12. //--------------------------

  13. ThreadLoader::ThreadLoader () : wakeup()
  14. {
  15.   thread = NULL ;
  16. }

  17. ThreadLoader::~ThreadLoader ()
  18. {
  19.   if ( thread != NULL )
  20.   {
  21.     ThreadRelease () ;
  22.     perror ("release method always called before free method") ;
  23.     return ;
  24.   }
  25. }


  26. int ThreadLoader::ThreadRelease ()
  27. {
  28.    char c_exit[19] = "thread obj release";
  29.    int len ;
  30.     
  31.    if ( thread == NULL )
  32.     return 0 ;
  33.  
  34.    len = wakeup.write_in_pipe (&c_exit, 18) ;
  35.   
  36.    if ( len != 18 )
  37.    {
  38.     perror ("write_in_pipe method goes error ") ;
  39.     return -1 ;
  40.    }

  41.    len = osip_thread_join (( struct osip_thread*)thread ) ;
  42.  
  43.    if ( len != 0 )
  44.    {
  45.     perror ("osip_thread_join method goes wrong") ;
  46.     return -1 ;
  47.    }
  48.    
  49.    free ( thread ) ;
  50.    thread = NULL ;
  51.     
  52.    return 0 ;
  53. }

  54. int ThreadLoader::ThreadStart ( void *(*loader)(void *) , void *arg_list )
  55. {
  56.    if ( loader == NULL )
  57.     return -1 ;
  58.    thread = (void*)osip_thread_create ( 20000 , loader , arg_list ) ;
  59.     
  60.    if ( thread == NULL )
  61.     return -1 ;
  62.    
  63.    return 0 ;
  64. }


  65. int ThreadLoader::ThreadWakeUp ()
  66. {
  67.     int ret ;
  68.     char c_wake[15] = "thread wake up" ;
  69.     
  70.     ret = wakeup.write_in_pipe( &c_wake, 14 ) ;
  71.     
  72.      if ( ret != 14 )
  73.     {
  74.      perror ("write_in_pipe method goes wrong") ;
  75.       return -1 ;
  76.     }
  77.     
  78.     return 0 ;
  79. }

  80. int ThreadLoader::ThreadPrintState ()
  81. {
  82.     int ret ;
  83.     char c_contents [1024] ;
  84.     
  85.     ret = wakeup.read_from_pipe ( &c_contents , 1024) ;
  86.     
  87.         c_contents[ret] = '\0' ;

  88.     if ( ret <= 0 )
  89.     {
  90.         perror ("read_from_pipe method goes wrong") ;
  91.         return -1 ;
  92.     }
  93.     
  94.     printf("pipe contents : %s \n\n",c_contents ) ;
  95.     
  96.      return 0 ;
  97. }

5. Main.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <string>
  4. #include <pthread.h>

  5. #include "ThreadLoader.h"

  6. using namespace std ;

  7. void* sayHi ( void *name )
  8. {
  9.   
  10.   cout << "hi "<< (const char*)name << endl ;
  11.   return NULL ;
  12. }

  13. void* sayHello ( void* name )
  14. {
  15.    cout << "hi " << (const char*)name << endl ;
  16.    return NULL ;
  17. }

  18. typedef void*(*func_ptr_t )(void*) ;


  19. int main ( int argc , char **argv )
  20. {
  21.   string name ;
  22.   ThreadLoader loader1 , loader2 ;
  23.   
  24.   func_ptr_t hello_ptr ,hi_ptr ;

  25.   hello_ptr = sayHello ;
  26.   hi_ptr = sayHi ;

  27.   cout << "test start method "<< endl ;

  28.   cout << "name" << endl ;
  29.   cin >> name ;
  30.   
  31.   loader1.ThreadStart (hi_ptr, (void*)name.c_str()) ;

  32.   sleep (2) ;


  33.   cout << "\n\nname" << endl ;
  34.   cin >> name ;
  35.   loader2.ThreadStart ( hello_ptr , (void*)name.c_str()) ;
  36.   sleep (2) ;
  37.  

  38.   cout << "here we test wake up method" << endl ;
  39.   loader1.ThreadWakeUp () ;
  40.   loader2.ThreadWakeUp () ;

  41. // cout << "print pipe pair contents tests "<< endl ;
  42. // loader1.ThreadPrintState () ;
  43. // loader2.ThreadPrintState () ;

  44.   cout << "test release method "<< endl ;
  45.   loader1.ThreadRelease () ;
  46.   loader2.ThreadRelease () ;

  47.   cout << "print pipe pair contents tests "<< endl ;
  48.   loader1.ThreadPrintState () ;
  49.   loader2.ThreadPrintState () ;

  50.   
  51.   return 0 ;
  52. }
end
阅读(2329) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~