c++多線程編程

一直對多線程編程這一塊很陌生,決定花一點時間整理一下。

os:ubuntu 10.04 ?c++

1.最基礎,進程同時創建5個線程,各自調用同一個函數

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>?//多線程相關操作頭文件,可移植眾多平臺??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5?//線程數??
  7. ??
  8. void*?say_hello(?void*?args?)??
  9. {??
  10. ????cout?<<?"hello..."?<<?endl;??
  11. }?//函數返回的是函數指針,便于后面作為參數??
  12. ??
  13. int?main()??
  14. {??
  15. ????pthread_t?tids[NUM_THREADS];?//線程id??
  16. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  17. ????{??
  18. ????????int?ret?=?pthread_create(?&tids[i],?NULL,?say_hello,?NULL?);?//參數:創建的線程id,線程參數,線程運行函數的起始地址,運行函數的參數??
  19. ????????if(?ret?!=?0?)?//創建線程成功返回0??
  20. ????????{??
  21. ????????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  22. ????????}??
  23. ????}??
  24. ????pthread_exit(?NULL?);?//等待各個線程退出后,進程才結束,否則進程強制結束,線程處于未終止的狀態??
  25. }??
輸入命令:g++ -o muti_thread_test_1 muti_thread_test_1.cpp -lpthread

注意:

1)此為c++程序,故用g++來編譯生成可執行文件,并且要調用處理多線程操作相關的靜態鏈接庫文件pthread。

2)-lpthread 編譯選項到位置可任意,如g++?-lpthread?-o muti_thread_test_1 muti_thread_test_1.cpp

3)注意gcc和g++的區別,轉到此文:點擊打開鏈接

測試結果:

[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_1??
  2. hello...hello...??
  3. hello...??
  4. hello...??
  5. ??
  6. hello...??
[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_1??
  2. hello...hello...hello...??
  3. ??
  4. hello...??
  5. hello...??

可知,兩次運行的結果會有差別,這不是多線程的特點吧?這顯然沒有同步?還有待進一步探索...

多線程的運行是混亂的,混亂就是正常?


2.線程調用到函數在一個類中,那必須將該函數聲明為靜態函數函數

因為靜態成員函數屬于靜態全局區,線程可以共享這個區域,故可以各自調用。

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5??
  7. ??
  8. class?Hello??
  9. {??
  10. public:??
  11. ????static?void*?say_hello(?void*?args?)??
  12. ????{??
  13. ????????cout?<<?"hello..."?<<?endl;??
  14. ????}??
  15. };??
  16. ??
  17. int?main()??
  18. {??
  19. ????pthread_t?tids[NUM_THREADS];??
  20. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  21. ????{??
  22. ????????int?ret?=?pthread_create(?&tids[i],?NULL,?Hello::say_hello,?NULL?);??
  23. ????????if(?ret?!=?0?)??
  24. ????????{??
  25. ????????????cout?<<?"pthread_create?error:error_code"?<<?ret?<<?endl;??
  26. ????????}??
  27. ????}??
  28. ????pthread_exit(?NULL?);??
  29. }??

測試結果:

[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_2??
  2. hello...??
  3. hello...??
  4. hello...??
  5. hello...??
  6. hello...??
[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_2??
  2. hello...hello...hello...??
  3. ??
  4. ??
  5. hello...??
  6. hello...??

3.如何在線程調用函數時傳入參數呢?

先看下面修改的代碼,傳入線程編號作為參數:

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>?//多線程相關操作頭文件,可移植眾多平臺??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5?//線程數??
  7. ??
  8. void*?say_hello(?void*?args?)??
  9. {??
  10. ????int?i?=?*(?(int*)args?);?//對傳入的參數進行強制類型轉換,由無類型指針轉變為整形指針,再用*讀取其指向到內容??
  11. ????cout?<<?"hello?in?"?<<?i?<<??endl;??
  12. }?//函數返回的是函數指針,便于后面作為參數??
  13. ??
  14. int?main()??
  15. {??
  16. ????pthread_t?tids[NUM_THREADS];?//線程id??
  17. ????cout?<<?"hello?in?main.."?<<?endl;??
  18. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  19. ????{??
  20. ????????int?ret?=?pthread_create(?&tids[i],?NULL,?say_hello,?(void*)&i?);?//傳入到參數必須強轉為void*類型,即無類型指針,&i表示取i的地址,即指向i的指針??
  21. ????????cout?<<?"Current?pthread?id?=?"?<<?tids[i]?<<?endl;?//用tids數組打印創建的進程id信息??
  22. ????????if(?ret?!=?0?)?//創建線程成功返回0??
  23. ????????{??
  24. ????????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  25. ????????}??
  26. ????}??
  27. ????pthread_exit(?NULL?);?//等待各個線程退出后,進程才結束,否則進程強制結束,線程處于未終止的狀態??
  28. }??
測試結果:
[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_3??
  2. hello?in?main..??
  3. Current?pthread?id?=?3078458224??
  4. Current?pthread?id?=?3070065520??
  5. hello?in?hello?in?2??
  6. 1??
  7. Current?pthread?id?=?hello?in?2??
  8. 3061672816??
  9. Current?pthread?id?=?3053280112??
  10. hello?in?4??
  11. Current?pthread?id?=?hello?in?4??
  12. 3044887408??
顯然不是想要的結果,調用順序很亂,這是為什么呢?

這是因為多線程到緣故,主進程還沒開始對i賦值,線程已經開始跑了...?

修改代碼如下:

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>?//多線程相關操作頭文件,可移植眾多平臺??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5?//線程數??
  7. ??
  8. void*?say_hello(?void*?args?)??
  9. {??
  10. ????cout?<<?"hello?in?thread?"?<<?*(?(int?*)args?)?<<??endl;??
  11. }?//函數返回的是函數指針,便于后面作為參數??
  12. ??
  13. int?main()??
  14. {??
  15. ????pthread_t?tids[NUM_THREADS];?//線程id??
  16. ????int?indexes[NUM_THREADS];?//用來保存i的值避免被修改??
  17. ??
  18. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  19. ????{??
  20. ????????indexes[i]?=?i;??
  21. ????????int?ret?=?pthread_create(?&tids[i],?NULL,?say_hello,?(void*)&(indexes[i])?);??
  22. ????????if(?ret?!=?0?)?//創建線程成功返回0??
  23. ????????{??
  24. ????????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  25. ????????}??
  26. ????}??
  27. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  28. ????????pthread_join(?tids[i],?NULL?);?//pthread_join用來等待一個線程的結束,是一個線程阻塞的函數??
  29. }??
測試結果:

[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_3??
  2. hello?in?thread?hello?in?thread?hello?in?thread?hello?in?thread?hello?in?thread?30124??

這是正常的嗎?感覺還是有問題...待續

代碼中如果沒有pthread_join主線程會很快結束從而使整個進程結束,從而使創建的線程沒有機會開始執行就結束了。加入pthread_join后,主線程會一直等待直到等待的線程結束自己才結束,使創建的線程有機會執行


4.線程創建時屬性參數的設置pthread_attr_t及join功能的使用

線程的屬性由結構體pthread_attr_t進行管理。

typedef struct
{
? ? int ? ? ? ? ? ? ? ? ? ? ? ? ? detachstate; ? ? 線程的分離狀態
? ? int ? ? ? ? ? ? ? ? ? ? ? ? ?schedpolicy; ? 線程調度策略
? ? struct sched_param ? ? ?schedparam; ? 線程的調度參數
? ? int inheritsched; 線程的繼承性?
? ? int scope; 線程的作用域?
? ? size_t guardsize; 線程棧末尾的警戒緩沖區大小?
? ? int stackaddr_set; void * stackaddr; 線程棧的位置?
? ? size_t stacksize; 線程棧的大小
}pthread_attr_t;

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5??
  7. ??
  8. void*?say_hello(?void*?args?)??
  9. {??
  10. ????cout?<<?"hello?in?thread?"?<<?*((?int?*?)args)?<<?endl;??
  11. ????int?status?=?10?+?*((?int?*?)args);?//線程退出時添加退出的信息,status供主程序提取該線程的結束信息??
  12. ????pthread_exit(?(?void*?)status?);???
  13. }??
  14. ??
  15. int?main()??
  16. {??
  17. ????pthread_t?tids[NUM_THREADS];??
  18. ????int?indexes[NUM_THREADS];??
  19. ??????
  20. ????pthread_attr_t?attr;?//線程屬性結構體,創建線程時加入的參數??
  21. ????pthread_attr_init(?&attr?);?//初始化??
  22. ????pthread_attr_setdetachstate(?&attr,?PTHREAD_CREATE_JOINABLE?);?//是設置你想要指定線程屬性參數,這個參數表明這個線程是可以join連接的,join功能表示主程序可以等線程結束后再去做某事,實現了主程序和線程同步功能??
  23. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  24. ????{??
  25. ????????indexes[i]?=?i;??
  26. ????????int?ret?=?pthread_create(?&tids[i],?&attr,?say_hello,?(?void*?)&(?indexes[i]?)?);??
  27. ????????if(?ret?!=?0?)??
  28. ????????{??
  29. ????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  30. ????}??
  31. ????}???
  32. ????pthread_attr_destroy(?&attr?);?//釋放內存???
  33. ????void?*status;??
  34. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  35. ????{??
  36. ????int?ret?=?pthread_join(?tids[i],?&status?);?//主程序join每個線程后取得每個線程的退出信息status??
  37. ????if(?ret?!=?0?)??
  38. ????{??
  39. ????????cout?<<?"pthread_join?error:error_code="?<<?ret?<<?endl;??
  40. ????}??
  41. ????else??
  42. ????{??
  43. ????????cout?<<?"pthread_join?get?status:"?<<?(long)status?<<?endl;??
  44. ????}??
  45. ????}??
  46. }??
測試結果:

[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_4??
  2. hello?in?thread?hello?in?thread?hello?in?thread?hello?in?thread?0hello?in?thread?321??
  3. ??
  4. ??
  5. ??
  6. 4??
  7. pthread_join?get?status:10??
  8. pthread_join?get?status:11??
  9. pthread_join?get?status:12??
  10. pthread_join?get?status:13??
  11. pthread_join?get?status:14??

5.互斥鎖的實現
互斥鎖是實現線程同步的一種機制,只要在臨界區前后對資源加鎖就能阻塞其他進程的訪問。

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>??
  3. ??
  4. using?namespace?std;??
  5. ??
  6. #define?NUM_THREADS?5??
  7. ??
  8. int?sum?=?0;?//定義全局變量,讓所有線程同時寫,這樣就需要鎖機制??
  9. pthread_mutex_t?sum_mutex;?//互斥鎖??
  10. ??
  11. void*?say_hello(?void*?args?)??
  12. {??
  13. ????cout?<<?"hello?in?thread?"?<<?*((?int?*?)args)?<<?endl;??
  14. ????pthread_mutex_lock(?&sum_mutex?);?//先加鎖,再修改sum的值,鎖被占用就阻塞,直到拿到鎖再修改sum;??
  15. ????cout?<<?"before?sum?is?"?<<?sum?<<?"?in?thread?"?<<?*(?(?int*?)args?)?<<?endl;??
  16. ????sum?+=?*(?(?int*?)args?);??
  17. ????cout?<<?"after?sum?is?"?<<?sum?<<?"?in?thread?"?<<?*(?(?int*?)args?)?<<?endl;??
  18. ????pthread_mutex_unlock(?&sum_mutex?);?//釋放鎖,供其他線程使用??
  19. ????pthread_exit(?0?);???
  20. }??
  21. ??
  22. int?main()??
  23. {??
  24. ????pthread_t?tids[NUM_THREADS];??
  25. ????int?indexes[NUM_THREADS];??
  26. ??????
  27. ????pthread_attr_t?attr;?//線程屬性結構體,創建線程時加入的參數??
  28. ????pthread_attr_init(?&attr?);?//初始化??
  29. ????pthread_attr_setdetachstate(?&attr,?PTHREAD_CREATE_JOINABLE?);?//是設置你想要指定線程屬性參數,這個參數表明這個線程是可以join連接的,join功能表示主程序可以等線程結束后再去做某事,實現了主程序和線程同步功能??
  30. ????pthread_mutex_init(?&sum_mutex,?NULL?);?//對鎖進行初始化??????
  31. ??
  32. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  33. ????{??
  34. ????????indexes[i]?=?i;??
  35. ????????int?ret?=?pthread_create(?&tids[i],?&attr,?say_hello,?(?void*?)&(?indexes[i]?)?);?//5個進程同時去修改sum??
  36. ????????if(?ret?!=?0?)??
  37. ????????{??
  38. ????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  39. ????}??
  40. ????}???
  41. ????pthread_attr_destroy(?&attr?);?//釋放內存???
  42. ????void?*status;??
  43. ????for(?int?i?=?0;?i?<?NUM_THREADS;?++i?)??
  44. ????{??
  45. ????int?ret?=?pthread_join(?tids[i],?&status?);?//主程序join每個線程后取得每個線程的退出信息status??
  46. ????if(?ret?!=?0?)??
  47. ????{??
  48. ????????cout?<<?"pthread_join?error:error_code="?<<?ret?<<?endl;??
  49. ????}??
  50. ????}??
  51. ????cout?<<?"finally?sum?is?"?<<?sum?<<?endl;??
  52. ????pthread_mutex_destroy(?&sum_mutex?);?//注銷鎖??
  53. }??
測試結果:
[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_5??
  2. hello?in?thread?hello?in?thread?hello?in?thread?410??
  3. before?sum?is?hello?in?thread?0?in?thread?4??
  4. after?sum?is?4?in?thread?4hello?in?thread???
  5. ??
  6. ??
  7. 2??
  8. 3??
  9. before?sum?is?4?in?thread?1??
  10. after?sum?is?5?in?thread?1??
  11. before?sum?is?5?in?thread?0??
  12. after?sum?is?5?in?thread?0??
  13. before?sum?is?5?in?thread?2??
  14. after?sum?is?7?in?thread?2??
  15. before?sum?is?7?in?thread?3??
  16. after?sum?is?10?in?thread?3??
  17. finally?sum?is?10??
可知,sum的訪問和修改順序是正常的,這就達到了多線程的目的了,但是線程的運行順序是混亂的,混亂就是正常?

6.信號量的實現
信號量是線程同步的另一種實現機制,信號量的操作有signal和wait,本例子采用條件信號變量pthread_cond_t tasks_cond;
信號量的實現也要給予鎖機制。

[html]?view plain?copy
  1. #include?<iostream>??
  2. #include?<pthread.h>??
  3. #include?<stdio.h>??
  4. ??
  5. using?namespace?std;??
  6. ??
  7. #define?BOUNDARY?5??
  8. ??
  9. int?tasks?=?10;??
  10. pthread_mutex_t?tasks_mutex;?//互斥鎖??
  11. pthread_cond_t?tasks_cond;?//條件信號變量,處理兩個線程間的條件關系,當task>5,hello2處理,反之hello1處理,直到task減為0??
  12. ??
  13. void*?say_hello2(?void*?args?)??
  14. {??
  15. ????pthread_t?pid?=?pthread_self();?//獲取當前線程id??
  16. ????cout?<<?"["?<<?pid?<<?"]?hello?in?thread?"?<<??*(?(?int*?)args?)?<<?endl;??
  17. ??????
  18. ????bool?is_signaled?=?false;?//sign??
  19. ????while(1)??
  20. ????{??
  21. ????pthread_mutex_lock(?&tasks_mutex?);?//加鎖??
  22. ????if(?tasks?>?BOUNDARY?)??
  23. ????{??
  24. ????????cout?<<?"["?<<?pid?<<?"]?take?task:?"?<<?tasks?<<?"?in?thread?"?<<?*(?(int*)args?)?<<?endl;??
  25. ????????--tasks;?//modify??
  26. ????}??
  27. ????else?if(?!is_signaled?)??
  28. ????{??
  29. ????????cout?<<?"["?<<?pid?<<?"]?pthread_cond_signal?in?thread?"?<<?*(?(?int*?)args?)?<<?endl;??
  30. ????????pthread_cond_signal(?&tasks_cond?);?//signal:向hello1發送信號,表明已經>5??
  31. ????????is_signaled?=?true;?//表明信號已發送,退出此線程??
  32. ????}??
  33. ????pthread_mutex_unlock(?&tasks_mutex?);?//解鎖??
  34. ????if(?tasks?==?0?)??
  35. ????????break;??
  36. ????}??????
  37. }??
  38. ??
  39. void*?say_hello1(?void*?args?)??
  40. {??
  41. ????pthread_t?pid?=?pthread_self();?//獲取當前線程id??
  42. ????cout?<<?"["?<<?pid?<<?"]?hello?in?thread?"?<<??*(?(?int*?)args?)?<<?endl;??
  43. ??
  44. ????while(1)??
  45. ????{??
  46. ????????pthread_mutex_lock(?&tasks_mutex?);?//加鎖??
  47. ????????if(?tasks?>?BOUNDARY?)??
  48. ????????{??
  49. ????????cout?<<?"["?<<?pid?<<?"]?pthread_cond_signal?in?thread?"?<<?*(?(?int*?)args?)?<<?endl;??
  50. ????????pthread_cond_wait(?&tasks_cond,?&tasks_mutex?);?//wait:等待信號量生效,接收到信號,向hello2發出信號,跳出wait,執行后續???
  51. ????????}??
  52. ????????else??
  53. ????????{??
  54. ????????cout?<<?"["?<<?pid?<<?"]?take?task:?"?<<?tasks?<<?"?in?thread?"?<<?*(?(int*)args?)?<<?endl;??
  55. ????????????--tasks;??
  56. ????}??
  57. ????????pthread_mutex_unlock(?&tasks_mutex?);?//解鎖??
  58. ????????if(?tasks?==?0?)??
  59. ????????????break;??
  60. ????}???
  61. }??
  62. ??
  63. ??
  64. int?main()??
  65. {??
  66. ????pthread_attr_t?attr;?//線程屬性結構體,創建線程時加入的參數??
  67. ????pthread_attr_init(?&attr?);?//初始化??
  68. ????pthread_attr_setdetachstate(?&attr,?PTHREAD_CREATE_JOINABLE?);?//是設置你想要指定線程屬性參數,這個參數表明這個線程是可以join連接的,join功能表示主程序可以等線程結束后再去做某事,實現了主程序和線程同步功能??
  69. ????pthread_cond_init(?&tasks_cond,?NULL?);?//初始化條件信號量??
  70. ????pthread_mutex_init(?&tasks_mutex,?NULL?);?//初始化互斥量??
  71. ????pthread_t?tid1,?tid2;?//保存兩個線程id??
  72. ????int?index1?=?1;??
  73. ????int?ret?=?pthread_create(?&tid1,?&attr,?say_hello1,?(?void*?)&index1?);??
  74. ????if(?ret?!=?0?)??
  75. ????{??
  76. ????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  77. ????}??
  78. ????int?index2?=?2;??
  79. ????ret?=?pthread_create(?&tid2,?&attr,?say_hello2,?(?void*?)&index2?);??
  80. ????if(?ret?!=?0?)??
  81. ????{??
  82. ????????cout?<<?"pthread_create?error:error_code="?<<?ret?<<?endl;??
  83. ????}??
  84. ????pthread_join(?tid1,?NULL?);?//連接兩個線程??
  85. ????pthread_join(?tid2,?NULL?);???
  86. ??
  87. ????pthread_attr_destroy(?&attr?);?//釋放內存???
  88. ????pthread_mutex_destroy(?&tasks_mutex?);?//注銷鎖??
  89. ????pthread_cond_destroy(?&tasks_cond?);?//正常退出??
  90. }??
測試結果:
先在線程2中執行say_hello2,再跳轉到線程1中執行say_hello1,直到tasks減到0為止。

[html]?view plain?copy
  1. wq@wq-desktop:~/coding/muti_thread$?./muti_thread_test_6??
  2. [3069823856]?hello?in?thread?2??
  3. [3078216560]?hello?in?thread?1[3069823856]?take?task:?10?in?thread?2??
  4. ??
  5. [3069823856]?take?task:?9?in?thread?2??
  6. [3069823856]?take?task:?8?in?thread?2??
  7. [3069823856]?take?task:?7?in?thread?2??
  8. [3069823856]?take?task:?6?in?thread?2??
  9. [3069823856]?pthread_cond_signal?in?thread?2??
  10. [3078216560]?take?task:?5?in?thread?1??
  11. [3078216560]?take?task:?4?in?thread?1??
  12. [3078216560]?take?task:?3?in?thread?1??
  13. [3078216560]?take?task:?2?in?thread?1??
  14. [3078216560]?take?task:?1?in?thread?1??
到此,對多線程編程有了一個初步的了解,當然還有其他實現線程同步的機制,有待進一步探索。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458723.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458723.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458723.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ajax當頁post請求,tag落地頁--通過ajax-post請求數據

查詢所有tag及其對應跳轉鏈接$tags get_tags(array(get>all));$output . ;if($tags) {foreach ($tags as $tag):$output . . $tag->name .;endforeach;} else {_e(No tags created., text-domain);}$output . ;echo $output;交互tag查詢image場景如下&#xff0c;通過頁…

GIT的PUSH指令

### GIT的PUSH指令 $ git push <遠程主機名> <本地分支名>:<遠程分支名> * git push命令用于將本地分支的更新&#xff0c;推送到遠程主機。 * 如果省略遠程分支名&#xff0c;則表示將本地分支推送到與之對應的遠程分支&#xff08;通常兩者同名&#xff…

Android 編程下 Touch 事件的分發和消費機制

Android 中與 Touch 事件相關的方法包括&#xff1a;dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev)&#xff1b;能夠響應這些方法的控件包括&#xff1a;ViewGroup、View、Activity。方法與控件的對應關系如下表所…

ios微信本地視頻上傳到服務器,ios本地視頻wx.uploadFile上傳

//上傳視頻uploadVideo:function(){let _this this;let list [camera, album];wx.showActionSheet({itemList: [拍攝視頻,從相冊選擇視頻,從視頻庫選擇視頻],success: function (res) {if(res.tapIndex0 || res.tapIndex1){wx.chooseVideo({sourceType:[list[res.tapIndex]],…

如何手工抓取dump文件及分析

在生產環境下進行故障診斷時&#xff0c;為了不終止正在運行的服務或應用程序&#xff0c;有兩種方式可以對正在運行的服務或應用程序的進程進行分析和調試。 首先一種比較直觀簡潔的方式就是用WinDbg等調試器直接attach到需要調試的進程&#xff0c;調試完畢之后再detach即可。…

Java 類加載機制詳解

2019獨角獸企業重金招聘Python工程師標準>>> 一、類加載器 類加載器&#xff08;ClassLoader&#xff09;&#xff0c;顧名思義&#xff0c;即加載類的東西。在我們使用一個類之前&#xff0c;JVM需要先將該類的字節碼文件&#xff08;.class文件&#xff09;從磁盤…

JAVA vo pojo javabean dto區別

JavaBean 是一種JAVA語言寫成的可重用組件。為寫成JavaBean&#xff0c;類必須是具體的和公共的&#xff0c;并且具有無參數的構造器。JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性。眾所周知&#xff0c;屬性名稱符合這種模式&#xff0c;其他Java 類可…

編寫的windows程序,崩潰時產生crash dump文件的辦法

一、引言 dump文件是C程序發生異常時&#xff0c;保存當時程序運行狀態的文件&#xff0c;是調試異常程序重要的方法&#xff0c;所以程序崩潰時&#xff0c;除了日志文件&#xff0c;dump文件便成了我們查找錯誤的最后一根救命的稻草。windows程序產生dump文件和linux程序產生…

Nginx+PHP實時生成不同尺寸圖片

原來圖片服務器采用Windows .net架構&#xff0c;鑒于需求需要生成各種尺寸圖片。流程說明:用戶從Nginx請求對應的圖片,判斷是否存在_200x300的對應參數&#xff0c;如果沒有就直接請求到對應目錄的原圖&#xff0c;否則繼續判斷是否在本地已經生成了對應的緩存圖片&#xff0c…

JavaScript設計模式 Item 2 -- 接口的實現

1、接口概述 1。什么是接口&#xff1f; 接口是提供了一種用以說明一個對象應該具有哪些方法的手段。盡管它可以表明這些方法的語義&#xff0c;但它并不規定這些方法應該如何實現。 2. 接口之利 促進代碼的重用。 接口可以告訴程序員一個類實現了哪些方法&#xff0c;從而幫助…

Spring Boot 樂觀鎖加鎖失敗 - 集成AOP

Spring Boot with AOP 手頭上的項目使用了Spring Boot&#xff0c; 在高并發的情況下&#xff0c;經常出現樂觀鎖加鎖失敗的情況&#xff08;OptimisticLockingFailureException&#xff0c;同一時間有多個線程在更新同一條數據&#xff09;。為了減少直接向服務使用者直接返回…

掌握VS2010調試 -- 入門指南

1 導言 在軟件開發周期中&#xff0c;測試和修正缺陷&#xff08;defect&#xff0c;defect與bug的區別&#xff1a;Bug是缺陷的一種表現形式&#xff0c;而一個缺陷是可以引起多種Bug的&#xff09;的時間遠多于寫代碼的時間。通常&#xff0c;debug是指發現缺陷并改正的過程。…

151031

create or replace procedure pr_test1 is v_case number(3): 100; beginif 2>1 thendbms_output.put_line(成立);elsif 4>3 thenif 7>6 thendbms_output.put_line(不成立);end if; elsif 6>5 thendbms_output.put_line(也行);elsedbms_output.put_line(也不成立);…

postgresql9.5 run 文件linux安裝后配置成開機服務

網上出現的比較多安裝方法要么是源碼安裝&#xff0c;要么是yum安裝&#xff0c;我發覺都要配置很多屬性&#xff0c;比較麻煩&#xff0c;所以現在我在centos7長用 run文件來安裝 http://get.enterprisedb.com/postgresql/postgresql-9.5.1-1-linux-x64.run 這里的安裝shell整…

Windows API GetProcAddress 及demo code

GetProcAddress函數檢索指定的動態鏈接庫(DLL)中的輸出庫函數地址。 函數原型&#xff1a; FARPROC GetProcAddress( HMODULE hModule, // DLL模塊句柄 LPCSTR lpProcName// 函數名 ); 參數&#xff1a; hModule [in] 包含此函數的DLL模塊的句柄。LoadLibrary、AfxLoadLibrary …

【操作系統】進程管理

進程管理 進程的基本概念 程序的順序執行及其特征 程序的順序執行:僅當前一操作(程序段)執行完后&#xff0c;才能執行后續操作。 程序順序執行時的特征&#xff1a;順序性&#xff0c;封閉性&#xff0c;可再見性。 前趨圖 前趨圖(Precedence Graph)是一個有向無循環圖&#…

va_list va_start va_end的使用

<pre name"code" class"cpp" style"color: rgb(51, 51, 51); white-space: pre-wrap; word-wrap: break-word;"><strong>一、 從printf()開始</strong> 從大家都很熟悉的格式化字符串函數開始介紹可變參數函數。 原型&#xf…

Linux學習之CentOS(三)----將Cent0S 7的網卡名稱eno16777736改為eth0

【正文】 Linux系統版本&#xff1a;CentOS_7&#xff08;64位&#xff09; 一、前言&#xff1a; 今天又從Centos 6.5裝回了Centos 7&#xff0c;畢竟還是要順應潮流嘛。安裝完成之后&#xff0c;發現發現CentOS 7默認的網卡名稱是eno16777736&#xff0c;如圖所示&#xff1a…

本地音頻播放,使用AVFoundation.framework中的AVAudioPlayer來實現

本地音頻播放,使用AVfoundation.framework中的AVAudioPlayer來實現 /*AVAudioPlayer的使用比較簡單: 1、初始化AVAudioPlayer對象&#xff0c;此時通常指定本地文件路徑 2、設置播放器屬性&#xff0c;例如重復次數、音量大小等 3、調用play方法播放。 */

AngularJS操作DOM——angular.element

addClass()-為每個匹配的元素添加指定的樣式類名after()-在匹配元素集合中的每個元素后面插入參數所指定的內容&#xff0c;作為其兄弟節點append()-在每個匹配元素里面的末尾處插入參數內容attr() - 獲取匹配的元素集合中的第一個元素的屬性的值bind() - 為一個元素綁定一個事…