24  pthread_testcancel ();

25  }

26

27 /*

28 * Cancellation cleanup handler for the contractor thread. It

29 * will cancel and detach each worker in the team.

30 */

31 void cleanup (void *arg)

32 {

33  team_t *team = (team_t *)arg;

34  int count, status;

35

36  for (count = team->join_i; count < THREADS; count++) {

37  status = pthread_cancel (team->workers[count]);

38  if (status != 0)

39  err_abort (status, 'Cancel worker');

40

41  status = pthread_detach(team->workers[count]);

42  if (status != 0)

43  err_abort (status, 'Detach worker');

44  printf ('Cleanup: canceled %d ', count);

45  }

46 }

47

48 /*

49 * Thread start routine for the contractor. It creates a team of

50 * worker threads, and then joins with them. When canceled, the

51 * cleanup handler will cancel and detach the remaining threads.

52 */

53 void *thread_routine (void *arg)

54 {

53  team_t team; /* team info */

56  int count;

57  void *result; /* Return status */

58  int status;

59

60  for (count = 0; count < THREADS; count++) {

61  status = pthread_create (

62  &team.workers[count], NULL, worker_routine, NULL);

63  if (status != 0)

64  err_abort (status, 'Create worker');

55  }

66  pthread_cleanup_push (cleanup, (void*)&team);

67

68  for (team.join_i = 0; team.join_i < THREADS; team.join_i++) {

69  status = pthread_join (team.workers[team.join_i], &result);

70  if (status != 0)

71  err_abort (status, 'Join worker');

72  }

73

74  pthread_cleanup_pop (0);

75  return NULL;

76 }

77

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

79 {

80  pthread_t thread_id;

81  int status;

82

83 #ifdef sun

84 /*

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

86 * that our threads can run concurrently, we need to

87 * increase the concurrency level to at least 2 plus THREADS

88 * (the number of workers).

89 */

90  DPRINTF (('Setting concurrency level to %d ', THREADS+2));

91  thr_setconcurrency (THREADS+2);

92 #endif

93  status = pthread_create (&thread_id, NULL, thread_routine, NULL);

94  if (status != 0)

95  err_abort (status, 'Create team');

96  sleep (5);

97  printf ('Cancelling... ');

98  status = pthread_cancel (thread_id);

99  if (status != 0)

100  err_abort (status, 'Cancel team');

101 status = pthread_join (thread_id, NULL);

102 if (status != 0)

103 err_abort (status, 'Join team');

104 }

5.4 Thread-specific data

No, I've made up my mind about it: if I'm Mabel, I'll stay down here. It'll be no use their putting their heads down and saying 'Come up again, dear!' I shall only look up and say 'Who am I, then? Tell me that first, and then, if I like being that person, I'll come up: if not, I'll stay down here till I'm somebody else.'

Lewis Carroll,Alice's Adventures in Wonderland

When a function in a single threaded program needs to create private data that persists across calls to that function, the data can be allocated statically in memory. The name's scope can be limited to the function or file that uses it (static) or it can be made global (extern).

It is not quite that simple when you use threads. All threads within a process share the same address space,

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

0

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

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