Chinaunix首页 | 论坛 | 博客
  • 博客访问: 276177
  • 博文数量: 65
  • 博客积分: 3091
  • 博客等级: 中校
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2005-01-25 09:44
文章存档

2013年(2)

2012年(11)

2011年(12)

2010年(13)

2009年(15)

2008年(12)

分类: C/C++

2013-06-05 13:55:35

多线程测试程序:

点击(此处)折叠或打开

  1. /*
  2. -* syncthread.cpp: test for synchronizing multiple threads
  3. -* Date: 2013-05-08
  4. */

  5. #include <cassert>
  6. #include <atomic>
  7. #include <thread> // for std::thread, not supported in gcc-4.8.0

  8. #include <boost/thread/thread.hpp>

  9. std::atomic<bool> x, y;
  10. std::atomic<int> z;
  11. std::atomic_int glbCnt;

  12. void write_x_then_y()
  13. {
  14.     x.store(true, std::memory_order_relaxed);
  15.     y.store(true, std::memory_order_release);
  16. }

  17. void read_y_then_x()
  18. {
  19.     while(!y.load(std::memory_order_acquire))
  20.     {
  21.         /* waiting */
  22.     }
  23.     if(x.load(std::memory_order_relaxed))
  24.         ++z;
  25. }

  26. int main_atomic(int argc, char **argv)
  27. {
  28.     x = false;
  29.     y = false;
  30.     z = 0;

  31.     //std::thread a(write_x_then_y);
  32.     boost::thread a(&write_x_then_y);
  33.     //std::thread b(read_y_then_x);
  34.     boost::thread b(&read_y_then_x);

  35.     a.join();
  36.     b.join();

  37.     assert(z.load()!=0);
  38.     return 0;
  39. }

  40. /////////////////////////////////////////////////

  41. int glbCountPeterson = 0;

  42. static bool flagA = 0;
  43. static bool flagB = 0;

  44. // must have "turn", otherwise the two threads
  45. // might introduce deadlock at both DETECT lines of "while..."
  46. static int glbSemaphore = 1;
  47. //static std::atomic<int> glbSemaphore;

  48. void PetersonA()
  49. {
  50.     flagA = true;
  51.     glbSemaphore = 0;

  52.     //DETECT:
  53.     while (flagB && (glbSemaphore == 0))
  54.     {
  55.         /* waiting */
  56.     }

  57.     // enter critical section
  58.     glbCountPeterson++;
  59.     // leave critical section
  60.     flagA = 0;
  61. }

  62. void PetersonB()
  63. {
  64.     flagB = true;
  65.     glbSemaphore = 1;

  66.     // DETECT
  67.     while (flagA && (glbSemaphore != 0))
  68.     {
  69.         /* waiting */
  70.     }

  71.     // enter critical setion
  72.     glbCountPeterson++;
  73.     // leave critical section
  74.     flagB = 0;
  75. }

  76. int ThreadFuncA( )
  77. {
  78.     int i;
  79.     //cout << "Starting Thread 1" << endl;
  80.     for (i = 0; i < 10000000; i++)
  81.     {
  82.         PetersonA();
  83.     }
  84.     return 0;
  85. }

  86. int ThreadFuncB( )
  87. {
  88.     int i;
  89.     //cout << "Starting Thread 2" << endl;
  90.     for (i = 0; i < 10000000; i++)
  91.     {
  92.         PetersonB();
  93.     }
  94.     return 0;
  95. }

  96. int main_peterson(int argc, char **argv)
  97. {
  98.     glbCountPeterson = 0;

  99.     flagA = false;
  100.     flagB = false;

  101.     glbSemaphore = 1;

  102.     boost::thread a(&ThreadFuncA);
  103.     boost::thread b(&ThreadFuncB);

  104.     a.join();
  105.     b.join();

  106.     std::cout << glbCountPeterson << std::endl;

  107.     if (glbCountPeterson == 20000000)
  108.         std::cout << "Success" << std::endl;
  109.     else
  110.         std::cout << "Fail" << std::endl;

  111.     return 0;
  112. }

  113. //////////////////////////////////////////////////////

  114. int numThreads = 3;
  115. int glbCountDijk = 0;
  116. //int attempFlag[3] = {0, 0, 0};
  117. std::atomic_int attempFlag[3];
  118. //int filterTurn[3] = {1, 1, 1};
  119. std::atomic_int filterTurn[3];

  120. int Dijk(int tid)
  121. {
  122.     int i = tid; // thread i (0 <= i < THREAD_NUM)
  123.     int j, k;
  124.     // attemp to enter critical section
  125.     for (j = 1; j < numThreads; j++) // N-1 times iteration
  126.     {
  127.         attempFlag[i] = j;
  128.         filterTurn[j] = i;
  129.         for (k = 0; k < numThreads; k++)
  130.         {
  131.             if (k == i) continue;
  132.             // different between "attempFlag[i] < attempFlag[k]" and "attempFlag[k] >= attempFlag[i]"?
  133.             //while (attempFlag[i] < attempFlag[k] && filterTurn[j] == i)
  134.             while (attempFlag[k] >= attempFlag[i] && filterTurn[j] == i)
  135.             {
  136.                 /* waiting */
  137.             }
  138.         }
  139.     }
  140.     // critical section
  141.     glbCountDijk++;
  142.     // leave critical section
  143.     attempFlag[i] = 0;

  144.     return 0;
  145. }

  146. void DijkA()
  147. {
  148.     int i = 0; // thread i (0 <= i < n)
  149.     int j, k;
  150.     // attemp to enter critical section
  151.     for (j = 1; j < numThreads; j++)
  152.     {
  153.         attempFlag[i] = j;
  154.         filterTurn[j] = i;
  155.         for (k = 0; k < numThreads; k++)
  156.         {
  157.             if (k == i) continue;
  158.             while (attempFlag[k] >= attempFlag[i] && filterTurn[j] == i)
  159.             {
  160.                 /* waiting */
  161.             }
  162.         }
  163.     }
  164.     // critical section
  165.     glbCountDijk++;
  166.     // leave critical section
  167.     attempFlag[i] = 0;
  168. }

  169. void DijkB()
  170. {
  171.     int i = 1; // thread i (0 <= i < n)
  172.     int j, k;
  173.     // attemp to enter critical section
  174.     for (j = 1; j < numThreads; j++)
  175.     {
  176.         attempFlag[i] = j;
  177.         filterTurn[j] = i;
  178.         for (k = 0; k < numThreads; k++)
  179.         {
  180.             if (k == i) continue;
  181.             while (attempFlag[k] >= attempFlag[i] && filterTurn[j] == i)
  182.             {
  183.                 /* waiting */
  184.             }
  185.         }
  186.     }
  187.     // critical section
  188.     glbCountDijk++;
  189.     // leave critical section
  190.     attempFlag[i] = 0;
  191. }

  192. void DijkC()
  193. {
  194.     int i = 2; // thread i (0 <= i < n)
  195.     int j, k;
  196.     // attemp to enter critical section
  197.     for (j = 1; j < numThreads; j++)
  198.     {
  199.         attempFlag[i] = j;
  200.         filterTurn[j] = i;
  201.         for (k = 0; k < numThreads; k++)
  202.         {
  203.             if (k == i) continue;
  204.             while (attempFlag[k] >= attempFlag[i] && filterTurn[j] == i)
  205.             {
  206.                 /* waiting */
  207.             }
  208.         }
  209.     }
  210.     // critical section
  211.     glbCountDijk++;
  212.     // leave critical section
  213.     attempFlag[i] = 0;
  214. }

  215. int ThreadA(int cnt)
  216. {
  217.     int i;
  218.     //cout << "Starting Thread 1" << endl;
  219.     for (i = 0; i < cnt; i++)
  220.     {
  221.         //DijkA();
  222.         Dijk(0); /* tid = 0 */
  223.     }
  224.     return 0;
  225. }

  226. int ThreadB(int cnt)
  227. {
  228.     int i;
  229.     //cout << "Starting Thread 1" << endl;
  230.     for (i = 0; i < cnt; i++)
  231.     {
  232.         //DijkB();
  233.         Dijk(1); /* tid = 1 */
  234.     }
  235.     return 0;
  236. }

  237. int ThreadC(int cnt)
  238. {
  239.     int i;
  240.     //cout << "Starting Thread 1" << endl;
  241.     for (i = 0; i < cnt; i++)
  242.     {
  243.         //DijkC();
  244.         Dijk(2); /* tid = 2 */
  245.     }
  246.     return 0;
  247. }

  248. int main_dijk(int argc, char **argv)
  249. {
  250.     int loop;

  251.     numThreads = 3;
  252.     glbCountDijk = 0;

  253.     attempFlag[0] = 0;
  254.     attempFlag[1] = 0;
  255.     attempFlag[2] = 0;

  256.     filterTurn[0] = 1;
  257.     filterTurn[1] = 1;
  258.     filterTurn[2] = 1;

  259.     loop = 10000000;

  260.     boost::thread a(&ThreadA, loop);
  261.     boost::thread b(&ThreadB, loop);
  262.     boost::thread c(&ThreadC, loop);

  263.     a.join();
  264.     b.join();
  265.     c.join();

  266.     std::cout << glbCountDijk << std::endl;

  267.     if (glbCountDijk == loop * numThreads)
  268.         std::cout << "Success" << std::endl;
  269.     else
  270.         std::cout << "Fail" << std::endl;

  271.     return 0;
  272. }

  273. ///////////////////////////////////////////////

  274. int main(int argc, char **argv)
  275. {
  276.     std::atomic_flag flag = ATOMIC_FLAG_INIT;
  277.     std::atomic_bool cond[3];

  278.     flag.test_and_set();
  279.     if (cond[0].is_lock_free())
  280.         std::cout << "lock is free" << std::endl;

  281.     main_atomic(argc, argv);
  282.     main_peterson(argc, argv);
  283.     main_dijk(argc, argv);

  284.     return 0;
  285. }

阅读(861) | 评论(0) | 转发(0) |
0

上一篇:C++11代码示例

下一篇:没有了

给主人留下些什么吧!~~