千家信息网

一、(LINUX 线程同步) 引入

发表于:2024-11-30 作者:千家信息网编辑
千家信息网最后更新 2024年11月30日,原创水平有限有误请指出线程相比进程有着先天的数据共享的优势,如下图,线程共享了进程除栈区以外的所有内存区域如下图所示:但是这种共享有时候也会带来问题,简单的考虑如下C++代码:点击(此处)折叠或打开{
千家信息网最后更新 2024年11月30日一、(LINUX 线程同步) 引入原创水平有限有误请指出

线程相比进程有着先天的数据共享的优势,如下图,线程共享了进程除栈区以外的所有内存区域如下图所示:


但是这种共享有时候也会带来问题,简单的考虑如下C++代码:

点击(此处)折叠或打开

  1. {
  2. int b = 0;
  3. b = a;
  4. a = b+1;
  5. return *this;
  6. }


就是临界区代码
后面将对他们进行描述,这里我们简单实用静态互斥锁进行解决这个问题。

点击(此处)折叠或打开

  1. //原子操作 加锁
  2. pthread_mutex_lock(&mtx);
  3. ++test;
  4. pthread_mutex_unlock(&mtx);
  5. //原子操作 解锁
  6. cout<<pthread_self() <<":";
  7. test.prit()
实际上我们就是保护了操作符重载的testc& operator++()
临界区的选择应该尽量小,避免对多线程的并发性产生较大的性能影响


具体代码如下:

点击(此处)折叠或打开

  1. /*************************************************************************
  2. > File Name: error.cpp
  3. > Author: gaopeng QQ:22389860 all right reserved
  4. > Mail: gaopp_200217@163.com
  5. > Created Time: Mon 15 May 2017 12:01:33 AM CST
  6. ************************************************************************/

  7. #include<iostream>
  8. #include <pthread.h>
  9. #include <string.h>
  10. #define MAXOUT 1000000
  11. using namespace std;

  12. static pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;


  13. class testc
  14. {
  15. private:
  16. int a;
  17. public:
  18. testc()
  19. {
  20. a = 1;
  21. }
  22. testc& operator++()
  23. {
  24. int b = 0;
  25. b = a;
  26. a = b+1;
  27. return *this;

  28. }
  29. void prit()
  30. {
  31. cout<<a<<endl;
  32. }
  33. };


  34. testc test = test;


  35. void* testp(void* arg)
  36. {
  37. int i = MAXOUT;

  38. while(i--)
  39. {
  40. //原子操作 加锁
  41. pthread_mutex_lock(&mtx);
  42. ++test;
  43. pthread_mutex_unlock(&mtx);
  44. //原子操作 解锁
  45. cout<<pthread_self() <<":";
  46. test.prit();
  47. }
  48. }




  49. int main(void)
  50. {
  51. pthread_t tid[3];
  52. int er;
  53. int i = 0;

  54. while(i<3)
  55. {

  56. if ((er = pthread_create(tid+i,NULL,testp,NULL) )!=0 )
  57. {
  58. strerror(er);
  59. return -1;
  60. }
  61. i++;
  62. }

  63. i = 0;

  64. while(i<3)
  65. {
  66. pthread_join(*(tid+i),NULL);
  67. i++;
  68. }
  69. cout<<"last numer: ";
  70. test.prit();
  71. }


注意:一个简单类型的i++也不一定是一个原子操作,所以在涉及到并发修改共享变量的时候一定要使用
线程同步手段。



作者微信:


0