You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.9KB

  1. //
  2. // "$Id: threads.cxx 8033 2010-12-15 12:11:16Z AlbrechtS $"
  3. //
  4. // Threading example program for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2010 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. #include <config.h>
  28. #if HAVE_PTHREAD || defined(WIN32)
  29. # include <FL/Fl.H>
  30. # include <FL/Fl_Double_Window.H>
  31. # include <FL/Fl_Browser.H>
  32. # include <FL/Fl_Value_Output.H>
  33. # include <FL/fl_ask.H>
  34. # include "threads.h"
  35. # include <stdio.h>
  36. # include <math.h>
  37. Fl_Thread prime_thread;
  38. Fl_Browser *browser1, *browser2;
  39. Fl_Value_Output *value1, *value2;
  40. int start2 = 3;
  41. void magic_number_cb(void *p)
  42. {
  43. Fl_Value_Output *w = (Fl_Value_Output*)p;
  44. w->labelcolor(FL_RED);
  45. w->redraw_label();
  46. }
  47. void* prime_func(void* p)
  48. {
  49. Fl_Browser* browser = (Fl_Browser*) p;
  50. Fl_Value_Output *value;
  51. int n;
  52. int step;
  53. char proud = 0;
  54. if (browser == browser2) {
  55. n = start2;
  56. start2 += 2;
  57. step = 12;
  58. value = value2;
  59. } else {
  60. n = 3;
  61. step = 2;
  62. value = value1;
  63. }
  64. // very simple prime number calculator !
  65. //
  66. // The return at the end of this function can never be reached and thus
  67. // will generate a warning with some compilers, however we need to have
  68. // a return statement or other compilers will complain there is no return
  69. // statement. To avoid warnings on all compilers, we fool the smart ones
  70. // into beleiving that there is a chance that we reach the end by testing
  71. // n>=0, knowing that logically, n will never be negative in this context.
  72. if (n>=0) for (;;) {
  73. int pp;
  74. int hn = (int)sqrt((double)n);
  75. for (pp=3; pp<=hn; pp+=2) if ( n%pp == 0 ) break;
  76. if (pp >= hn) {
  77. char s[128];
  78. sprintf(s, "%d", n);
  79. // Obtain a lock before we access the browser widget...
  80. Fl::lock();
  81. browser->add(s);
  82. browser->bottomline(browser->size());
  83. if (n > value->value()) value->value(n);
  84. n += step;
  85. // Release the lock...
  86. Fl::unlock();
  87. // Send a message to the main thread, at which point it will
  88. // process any pending redraws for our browser widget. The
  89. // message we pass here isn't used for anything, so we could also
  90. // just pass NULL.
  91. Fl::awake(p);
  92. if (n>10000 && !proud) {
  93. proud = 1;
  94. Fl::awake(magic_number_cb, value);
  95. }
  96. } else {
  97. // This should not be necessary since "n" and "step" are local variables,
  98. // however it appears that at least MacOS X has some threading issues
  99. // that cause semi-random corruption of the (stack) variables.
  100. Fl::lock();
  101. n += step;
  102. Fl::unlock();
  103. }
  104. }
  105. return 0L;
  106. }
  107. int main(int argc, char **argv)
  108. {
  109. Fl_Double_Window* w = new Fl_Double_Window(200, 200, "Single Thread");
  110. browser1 = new Fl_Browser(0, 0, 200, 175);
  111. w->resizable(browser1);
  112. value1 = new Fl_Value_Output(100, 175, 200, 25, "Max Prime:");
  113. w->end();
  114. w->show(argc, argv);
  115. w = new Fl_Double_Window(200, 200, "Six Threads");
  116. browser2 = new Fl_Browser(0, 0, 200, 175);
  117. w->resizable(browser2);
  118. value2 = new Fl_Value_Output(100, 175, 200, 25, "Max Prime:");
  119. w->end();
  120. w->show();
  121. browser1->add("Prime numbers:");
  122. browser2->add("Prime numbers:");
  123. // Enable multi-thread support by locking from the main
  124. // thread. Fl::wait() and Fl::run() call Fl::unlock() and
  125. // Fl::lock() as needed to release control to the child threads
  126. // when it is safe to do so...
  127. Fl::lock();
  128. // Start threads...
  129. // One thread displaying in one browser
  130. fl_create_thread(prime_thread, prime_func, browser1);
  131. // Several threads displaying in another browser
  132. fl_create_thread(prime_thread, prime_func, browser2);
  133. fl_create_thread(prime_thread, prime_func, browser2);
  134. fl_create_thread(prime_thread, prime_func, browser2);
  135. fl_create_thread(prime_thread, prime_func, browser2);
  136. fl_create_thread(prime_thread, prime_func, browser2);
  137. fl_create_thread(prime_thread, prime_func, browser2);
  138. Fl::run();
  139. return 0;
  140. }
  141. #else
  142. # include <FL/fl_ask.H>
  143. int main() {
  144. fl_alert("Sorry, threading not supported on this platform!");
  145. }
  146. #endif // HAVE_PTHREAD || WIN32
  147. //
  148. // End of "$Id: threads.cxx 8033 2010-12-15 12:11:16Z AlbrechtS $".
  149. //