209  stderr,

210  'Thread %d: %s is type %o (%s)) ',

211  mine->index,

212  work->path,

213  filestat.st_mode & S_IFMT,

214  (S_ISFIFO (filestat.st_mode) ? 'FIFO'

215  :(S_ISCHR (filestat.st_mode) ? 'CHR'

216  :(S_ISBLK (filestat.st_mode) ? 'BLK'

217  :(S_ISSOCK (filestat.st_mode) ? 'SOCK'

218  :'unknown')))));

219

220  free (work->path); /* Free path buffer */

221  free (work); /* We're done with this */

222

223 /*

224 * Decrement count of outstanding work items, and wake

225 * waiters (trying to collect results or start a new

226 * calculation) if the crew is now idle.

227 *

228 * It's important that the count be decremented AFTER

229 * processing the current work item. That ensures the

230 * count won't go to 0 until we're really done.

231 */

232  status = pthread_mutex_lock (&crew->mutex);

233  if (status != 0)

234  err_abort (status, 'Lock crew mutex');

235

236  crew->work_count--;

237  DPRINTF (('Crew %d decremented work to %d ', mine->index,

238  crew->work_count));

239  if (crew->work_count <= 0) {

240  DPRINTF (('Crew thread %d done ', mine->index));

241  status = pthread_cond_broadcast (&crew->done);

242  if (status != 0)

243  err_abort (status, 'Wake waiters');

244  status = pthread_mutex_unlock (&crew->mutex);

245  if (status != 0)

246  err_abort (status, 'Unlock mutex');

247  break;

248  }

249

250  status = pthread_mutex_unlock (&crew->mutex);

251  if (status != 0)

252  err_abort (status, 'Unlock mutex');

253

254 }

255

256 free (entry);

257 return NULL;

258 }

Part 3 shows crew_create, the function used to create a new work crew. This simple example does not provide a way to destroy a work crew, because that is not necessary — the work crew would be destroyed only when the main program was prepared to exit, and process exit will destroy all threads and process data.

12-15 The crew_create function begins by checking the crew_size argument.The size of the crew is not allowed to exceed the size of the crew array in crew_t. If the requested size is acceptable, copy it into the structure.

16-31 Start with no work and an empty work queue. Initialize the crew's synchronization objects.

36-43 Then, for each crew member, initialize the member's worker_t data. The index of the member within the crew array is recorded, and a pointer back to the crew_t. Then the crew member thread is created, with a pointer to the member's worker_t as its argument.

¦ crew.c part 3 crew_create

1 /*

2 * Create a work crew.

3 */

4 int crew_create (crew_t *crew, int crew_size)

5 {

6 int crew_index;

7 int status;

8

9 /*

10 * We won't create more than CREW_SIZE members.

11 */

12 if (crew_size > CREW_SIZE)

13 return EINVAL;

14

15 crew->crew_size = crew_size;

16 crew->work_count = 0;

17 crew->first = NULL;

18 crew->last = NULL;

19

20 /*

21 * Initialize synchronization objects.

22 */

23 status = pthread_mutex_init (&crew->mutex, NULL);

24 if (status != 0)

25 return status;

26 status = pthread_cond_init (&crew->done, NULL);

27 if (status != 0)

28 return status;

29 status = pthread_cond_init (&crew->go, NULL);

30 if (status != 0)

31 return status;

32

33 /*

34 * Create the worker threads.

35 */

36 for (crew_index = 0; crew_index < CREW_SIZE; crew_index++) {

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

0

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

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