forked from shihyu/DesignPatternExample
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththread_pool.c
More file actions
128 lines (101 loc) · 3.13 KB
/
Copy paththread_pool.c
File metadata and controls
128 lines (101 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include "base.h"
#include "icommand.h"
#include "iblockingqueue.h"
#include "linked_blockingqueue.h"
#include "thread_pool.h"
static void ThreadPool_setThreadCount(ThreadPool*, int);
static void ThreadPool_start(ThreadPool*);
static void ThreadPool_stop(ThreadPool*);
static void ThreadPool_execute(ThreadPool*, ICommand*);
static void* ThreadPool_run(void* arg);
static void ThreadPool_doNothing()
{
}
static struct {
union {
ICommand;
ICommand icommand;
};
} stopCommand = {.execute = ThreadPool_doNothing};
ThreadPool* ThreadPool_construct(void* addr, int threadCount)
{
if (addr == NULL) {
return NULL;
}
ThreadPool* threadPool = addr;
threadPool->isStop = 1;
threadPool->threadCount = threadCount;
threadPool->tids = NULL;
threadPool->tidSize = 0;
threadPool->blockingQueue = &new(LinkedBlockingQueue)->iblockingQueue;
if (threadPool->blockingQueue == NULL) {
return NULL;
}
threadPool->start = ThreadPool_start;
threadPool->stop = ThreadPool_stop;
threadPool->execute = ThreadPool_execute;
threadPool->setThreadCount = ThreadPool_setThreadCount;
return threadPool;
}
void ThreadPool_destruct(ThreadPool* threadPool)
{
LinkedBlockingQueue* linkedBlockingQueue = container_of(
threadPool->blockingQueue, LinkedBlockingQueue, iblockingQueue);
delete(LinkedBlockingQueue, linkedBlockingQueue);
}
void ThreadPool_setThreadCount(ThreadPool* threadPool, int threadCount)
{
threadPool->threadCount = threadCount;
}
void* ThreadPool_run(void* arg)
{
ThreadPool* threadPool = arg;
while (!threadPool->isStop) {
ICommand* command = threadPool->blockingQueue->pop(
&threadPool->blockingQueue->iqueue);
command->execute(command);
}
return NULL;
}
void ThreadPool_start(ThreadPool* threadPool)
{
threadPool->isStop = 0;
if (threadPool->tidSize < threadPool->threadCount) {
free(threadPool->tids);
threadPool->tids =
malloc(sizeof(pthread_t) * threadPool->threadCount);
threadPool->tidSize = threadPool->threadCount;
}
int i;
for (i = 0; i < threadPool->threadCount; ++i) {
int err = pthread_create(threadPool->tids + i, NULL,
ThreadPool_run, threadPool);
if (err) {
fprintf(stderr, "pthread_create error. [err=%s]\n",
strerror(err));
}
}
}
void ThreadPool_stop(ThreadPool* threadPool)
{
threadPool->isStop = 1;
int i;
for (i = 0; i < threadPool->threadCount; ++i) {
threadPool->execute(threadPool, &stopCommand.icommand);
}
for (i = 0; i < threadPool->tidSize; ++i) {
int err = pthread_join(threadPool->tids[i], NULL);
if (err) {
fprintf(stderr, "pthread_join error. [err=%s]\n",
strerror(err));
}
}
}
void ThreadPool_execute(ThreadPool* threadPool, ICommand* command)
{
threadPool->blockingQueue->push(&threadPool->blockingQueue->iqueue,
command);
}