linux C++ 多线程编程

1.Solaris .vs. Linux Posix 库
Solaris 库(lib 线程)Linux POSIX 库(libp 线程)操作
sema_destroy()sem_destroy()销毁信号状态。
sema_init()sem_init()初始化信号。
sema_post()sem_post()增加信号。
sema_wait()sem_wait()阻止信号计数。
sema_trywait()sem_trywait()减少信号计数。
mutex_destroy()pthread_mutex_destroy()销毁或禁用与互斥对象相关的状态。
mutex_init()pthread_mutex_init()初始化互斥变量。
mutex_lock()pthread_mutex_lock()锁定互斥对象和块,直到互斥对象被释放。
mutex_unlock()pthread_mutex_unlock()释放互斥对象。
cond_broadcast()pthread_cond_broadcast()解除对等待条件变量的所有线程的阻塞。
cond_destroy()pthread_cond_destroy()销毁与条件变量相关的任何状态。
cond_init()pthread_cond_init()初始化条件变量。
cond_signal()pthread_cond_signal()解除等待条件变量的下一个线程的阻塞。
cond_wait()pthread_cond_wait()阻止条件变量,并在最后释放它。
rwlock_init()pthread_rwlock_init()初始化读/写锁。
rwlock_destroy()pthread_rwlock_destroy()锁定读/写锁。
rw_rdlock()pthread_rwlock_rdlock()读取读/写锁上的锁。
rw_wrlock()pthread_rwlock_wrlock()写读/写锁上的锁。
rw_unlock()pthread_rwlock_unlock()解除读/写锁。
rw_tryrdlock()pthread_rwlock_tryrdlock()读取非阻塞读/写锁上的锁。
rw_trywrlock()pthread_rwlock_trywrlock()写非阻塞读/写锁上的锁。
 
  1. 如何在linux 下c++中类的成员函数中创建多线程
  2. linux系统中线程程序库是POSIX pthread。POSIX pthread它是一个c的库,用C语言进行多线程编程我这里就不多说了,网上的例子很多。但是如何在C++的类中实现多线程编程呢?如果套用C语言中创建多线程的方式,在编译的时候会出现...does not match `void*(*)(void*)..这样的错误。出现这种情况的原因是,编译器在处理C++和C文件上是不同的,也就是说C++和C语言里边指针函数不等价。解决这种错误的方法
  3. 有两种:
  4. 1、不要将线程函数定义为类的成员函数,但是在类的成员函数里边调用它。
  5. 例如:
  6. [test.h]
  7. #ifndef TEST_H
  8. #define TEST_H
  9. class test
  10. {
  11. public:
  12.     test();
  13.     ~test();
  14. private:
  15.     void createThread();
  16. };
  17. #endif
  18. [test.cpp]
  19. test::test()
  20. {}
  21. test::~test()
  22. {}
  23. void *threadFunction()
  24. {
  25.     printf("This is a thread");
  26.     for(;;);
  27. }
  28. void test::createThread()
  29. {
  30.     pthread_t threadID;
  31.     pthread_create(&threadID, NULL, threadFunction, NULL);
  32. }
  33. [main.cpp]
  34. #inlcude "test.h"
  35. int main()
  36. {
  37.     test t;
  38.     t.createThead();
  39.     for(;;);
  40.     return 0;
  41. }
  42. 2、将线程函数作为类的成员函数,那么必须声明改线程函数为静态的函数,并且该线程函数所引用的其他成员函数也必须是静态的,如果要使用类的成员变量,则必须在创建线程的时候通过void *指针进行传递。
  43. 例如:
  44. 【test.h】
  45. #ifndef TEST_H
  46. #define TEST_H
  47. class test
  48. {
  49. public:
  50.     test();
  51.     ~test();
  52. private:
  53.     int p;
  54.     static void *threadFction(void *arg);
  55.     static void sayHello(int r);
  56.     void createThread();
  57. };
  58. #endif
  59. [test.cpp]
  60. test::test()
  61. {}
  62. test::~test()
  63. {}
  64. void *test::threadFunction(void *arg)
  65. {
  66.     int m = *(int *)arg;
  67.     sayHello(m);
  68.     for(;;);
  69. }
  70. void sayHello(int r)
  71. {
  72.     printf("Hello world %d!\n", r);
  73. }
  74. void test::createThread()
  75. {
  76.     pthread_t threadID;
  77.     pthread_create(&threadID, NULL, threadFunction, NULL);
  78. }
  79. [main.cpp]
  80. #inlcude "test.h"
  81. int main()
  82. {
  83.     test t;
  84.     t.createThead();
  85.     for(;;);
  86.     return 0;
  87. }
  88. ====================================================================================
  89.  http://bigbossman.blogbus.com/logs/10761605.html

  90.  Linux下的编程一直是C语言的天下,但老是用C感觉写的很乏味。用面向对象方法编程,听着都倍有面子。于是决定先在的这个项目用C++来写。虽然不一定能“以C++的思想”来写C++,少会有C++的样子。


  91. 但是问题来了:我需要在程序中动态创建一个线程,而pthread不接受C++类的成员函数作为参数。

  92. 原因也很简单,类成员是在类被实例化成为对象后才存在的,即在编译时是不存在的,编译器无法取得函数的确切入口地址,自然无法通过编译。

  93. 照这个分析,如果把要调用的类成员函数声明为静态的,pthread_create就可以找到函数的地址了。但这样一来的话,由于类中的静态函数无法调用类的非静态成员。线程函数的功能就受到了很大限制,也就没有比要将其放在类中了。

  94. 最容易想到的解决方案就是写个C函数,然后再C函数中调用C++对象的成员函数。

  95. 比如类为

  96. class foo(){

  97.     public :
  98.         thread();

  99. }

  100. class *f;

  101. void *bar(void *arg){

  102.     f->thread(); 

  103.     return NULL;
  104. }

  105. int main(){

  106.     .........
  107.     f=new foo();
  108.     
  109.     pthread_create(&tid,&tattr,bar,NULL);

  110. }

  111. 显然这种发法太笨了,而且对象只能是全局的。

  112. 注意到线程函数bar可以有一个任意类型的指针作为参数,那我们何不将对象通过这个指针将对象变为bar的一个参数,从而让我们的程序好看一些。

  113. class foo(){

  114.     public :
  115.         thread();

  116. }


  117. void *bar(void *args){

  118.     foo *f=(foo *)args;

  119.     f.thread(); 

  120.     return NULL;
  121. }

  122. int main(){

  123.     .........
  124.     foo *f=new foo();
  125.     pthread_create(&tid,&tattr,bar,f);

  126. }

  127. 如果把上述两种方法结合起来即对象中的静态函数+通过指针参数传递对象,那又会怎么样呢?

  128. class foo(){

  129.     public :
  130.         int thread();

  131.         static void *wrapper(void *args){
  132.             foo *f=static_cast<foo *>(args);
  133.             f->thread();
  134.             return NULL;
  135.         }

  136. }


  137. int main(){

  138.     .........
  139.     foo *f=new foo();
  140.     pthread_create(&tid,&tattr,foo::wrapper,&f);

  141. }

  142.  其他参考网页

  143.  http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/index.html

  144.  http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值