since user mode threads are not timesliced on Solaris.

¦ cancel_async.c

1 #include <pthread.h>

2 #include 'errors.h' 3

4 #define SIZE 10 /* array size */

5

6 static int matrixa[SIZE][SIZE];

7 static int matrixb[SIZE][SIZE];

8 static int matrixc[SIZE][SIZE]; 9

10 /*

11 * Loop until canceled. The thread can be canceled at any

12 * point within the inner loop, where asynchronous cancellation

13 * is enabled. The loop multiplies the two matrices matrixa

14 * and matrixb.

15 */

16 void *thread_routine (void *arg)

17 {

18 int cancel_type, status;

19 int i, j, k, value = 1;

20

21 /*

22 * Initialize the matrices to something arbitrary.

23 */

24 for (i = 0; i < SIZE; i++)

25 for (j = 0; j < SIZE; j++) {

26 matrixa[i][j] = i;

27 matrixb[i][j] = j;

28 }

29

30 while (1) {

31 /*

32 * Compute the matrix product of matrixa and matrixb.

33 */

34 status = pthread_setcanceltype (

35 PTHREAD_CANCEL_ASYNCHRONOUS,

36 &cancel_type);

37 if (status != 0)

38 err_abort (status, 'Set cancel type');

39 for (i = 0; i < SIZE; i++)

40 for (j = 0; j < SIZE; j++) {

41 matrixc[i][j] = 0;

42 for (k = 0; k < SIZE; k++)

43 matrixc[i][j] += matrixa[i][k] * matrixb[k][j];

44 }

45 status = pthread_setcanceltype (

46 cancel_type,

47 &cancel_type);

48 if (status != 0)

49 err_abort (status, 'Set cancel type');

50

51 /*

52 * Copy the result (matrixc) into matrixa to start again

53 */

54 for (i = 0; i < SIZE; i++)

55 for (j = 0; j < SIZE; j++)

56 matrixa[i][j] = matrixc[i][j];

57 }

58 }

59

60 int main (int argc, char *argv[])

61 {

62 pthread_t thread_id;

63 void *result;

64 int status; 65

66 #ifdef sun

67 /*

68 * On Solaris 2.5, threads are not timesliced. To ensure

69 * that our two threads can run concurrently, we need to

70 * increase the concurrency level to 2.

71 */

72 DPRINTF (('Setting concurrency level to 2 '));

73 thr_setconcurrency (2);

74 #endif

75 status = pthread_create (

76 &thread_id, NULL, thread_routine, NULL);

77 if (status != 0)

78 err_abort (status, 'Create thread');

79 sleep (1);

80 status = pthread_cancel (thread_id);

81 if (status != 0)

82 err_abort (status, 'Cancel thread');

83 status = pthread_join (thread_id, &result);

84 if (status != 0)

85 err_abort (status, 'Join thread');

86 if (result == PTHREAD_CANCELED)

87 printf ('Thread canceled ');

88 else

89 printf ('Thread was not canceled ');

90 return 0;

91 }

Warning: do not let 'DCE threads'' habits carry over to Pthreads!

I'll end this section with a warning. DCE threads, a critical component of the Open Software Foundation's Distributed Computing Environment, was designed to be independent of the underlying UNIX kernel. Systems with no thread support at all often emulated 'thread synchronous' I/O in user mode, using nonblocking I/O mode, so that a thread attempting I/O on a busy file was blocked on a condition variable until a later select or poll showed that the I/O could complete. DCE listener threads might block indefinitely on a socket read, and it was important to be able to cancel that read.

When DCE was ported to newer kernels that had thread support, but not Pthreads support, the user mode I/O wrappers were usually omitted, resulting in a thread blocked within a kernel that did not support deferred

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату