线程池+时间片轮转法调度+连续内存管理+内存调度
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <semaphore.h> 5 #include <unistd.h> 6 #include <time.h> 7 #include <sys/types.h> 8 #include <pthread.h> 9 #define bool int 10 #define true 1 11 #define false 0 12 #define THREAD_MAXN 100//线程数 13 #define RUNTIME_SUB 1//每次运行线程减去的运行时间 14 #define RUN_TIME 100//线程运行时间 15 #define TASK_NUM 10000//任务数 16 //-----结构体定义 17 typedef struct TCB//存储线程信息 18 { 19 int thread_id;//线程编号 20 int arriveTime;//线程到达时间 21 int runTime;//持续时间 22 int finishTime;//完成时间 23 int wholeTime;//周转时间 24 double weightWholeTime;//带权周转时间 25 bool Finished;//线程是否完成 26 struct TCB* next;//使用链式存储方式 27 }TCB; 28 struct TCB_counterpart 29 { 30 struct TCB *father; 31 struct TCB_counterpart *next; 32 }; 33 struct task 34 { 35 void *(*task_func)(void *param); 36 void *param; 37 struct task *next; 38 }; 39 struct tcb_queue//TCB队列定义 40 { 41 struct TCB* tcbQueue[THREAD_MAXN+1];//TCB指针数组 42 int r, f; 43 }; 44 struct thread_pool//线程池结构体 45 { 46 pthread_mutex_t tcb_lock;//互斥锁 47 int fDestroyed;//线程池是否被销毁 48 pthread_t* threadid;//存储线程标识符指针 49 struct TCB* nowRunThread;//指向当前正在运行的线程 50 int nFinish;//完成线程数 51 sem_t sem[THREAD_MAXN+1];//用于控制线程的信号量 52 struct tcb_queue rrQueue;//轮转队列 53 struct tcb_queue showQueue;//用于辅助打印的队列 54 struct TCB_counterpart *nowPullQueue; 55 struct task *task_queue;//任务队列 56 int task_num; 57 struct TCB* tcb;//存储TCB 58 }; 59 //-----全局变量定义 60 static struct thread_pool* pool = NULL;//全局变量pool,指向线程池 61 int nowTime = -1;//当前已走过的时间 62 //-----函数声明 63 void TCB_bubble();//给TCB排序 64 void add_task (void *(*task_func)(void *param)); 65 void task_init(); 66 void show_rr();//打印轮转队列 67 void show_tcb();//打印所有线程的信息 68 void pool_init();//初始化线程池 69 void* thread_run_func(void* param);//线程里运行的函数 70 void round_robin();//时间片轮转算法的调度函数 71 int pool_destroy();//销毁线程池 72 void* task_run(); 73 void pull_thread(); 74 void enqueue(struct tcb_queue *q, struct TCB* tcb); 75 struct TCB* dequeue(struct tcb_queue *q); 76 struct TCB* get_front(struct tcb_queue *q); 77 bool empty(struct tcb_queue *q); 78 struct TCB_counterpart* create_TCB_counterpart(); 79 void insert_counterpart(struct TCB *tcb); 80 //main 81 int main() 82 { 83 pool_init(); 84 TCB_bubble(); 85 show_tcb(); 86 task_init(); 87 round_robin(); 88 sleep(3); 89 pool_destroy(); 90 return 0; 91 } 92 //函数定义 93 void TCB_bubble()//给TCB排序,按arriveTime升序排列 94 { 95 TCB* ptemp = NULL; 96 for (int i = 0; i < THREAD_MAXN+1; ++i) 97 { 98 ptemp = pool->tcb; 99 int f = 0; 100 while (ptemp && ptemp->next) 101 { 102 if (ptemp->arriveTime > ptemp->next->arriveTime) 103 {//交换两个节点 104 f = 1; 105 TCB* p_next = ptemp->next->next; 106 TCB* p_pre = ptemp;//后面ptemp = ptemp->next,当前ptemp相当于pre 107 TCB* p_pre_pre = pool->tcb;//pre的pre 108 if (p_pre_pre == p_pre)//说明ptemp是头结点 109 { 110 p_pre_pre = NULL; 111 } 112 else//否则找到pre_pre所在位置 113 { 114 while (p_pre_pre && p_pre_pre->next != p_pre) 115 { 116 p_pre_pre = p_pre_pre->next; 117 } 118 } 119 //交换结点 120 ptemp = ptemp->next; 121 ptemp->next = p_pre; 122 p_pre->next = p_next; 123 if (p_pre_pre) 124 { 125 p_pre_pre->next = ptemp; 126 } 127 else 128 { 129 pool->tcb = ptemp; 130 } 131 } 132 ptemp = ptemp->next; 133 } 134 if(f == 0) return; 135 } 136 } 137 void show_rr()//打印轮转队列 138 { 139 if (empty(&(pool->rrQueue))) 140 { 141 printf("目前还没有线程在队列中\n"); 142 } 143 else 144 { 145 printf("目前轮转队列为:\n"); 146 } 147 while (!empty(&(pool->rrQueue))) 148 { 149 enqueue(&(pool->showQueue), get_front(&(pool->rrQueue))); 150 printf("%d ", dequeue(&(pool->rrQueue))->thread_id); 151 } 152 while (!empty(&(pool->showQueue)))//将队列放回 153 { 154 enqueue(&(pool->rrQueue), dequeue(&(pool->showQueue))); 155 } 156 printf("\n"); 157 } 158 void show_tcb()//打印所有线程的信息 159 { 160 TCB* ptemp = pool->tcb; 161 printf("打印所有线程的信息:\n"); 162 while (ptemp) 163 { 164 printf("线程%d:到达时间:%d,剩余时间:%d\n", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime); 165 ptemp = ptemp->next; 166 } 167 printf("\n"); 168 } 169 void pool_init()//初始化线程池 170 { 171 pool = (struct thread_pool*)malloc(sizeof(struct thread_pool)); 172 pthread_mutex_init(&(pool->tcb_lock), NULL);//初始为未锁住状态 173 pool->fDestroyed = 0;//线程池是否被销毁 174 pool->nFinish = 0; 175 pool->task_num = 0; 176 pool->nowRunThread = NULL;//指向当前正在运行的线程 177 pool->rrQueue.f = pool->rrQueue.r = 0;//轮转队列 178 pool->showQueue.r = pool->showQueue.r = 0;//用于辅助打印的队列 179 pool->task_queue = NULL; 180 pool->nowPullQueue = NULL; 181 pool->tcb = NULL; 182 //创建并初始化TCB 183 TCB* ptemp = pool->tcb; 184 srand(time(0)); 185 for (int i = 0; i < THREAD_MAXN; ++i) 186 { 187 TCB* s = (TCB*)malloc(sizeof(TCB)); 188 // s->arriveTime = rand()%9; 189 s->arriveTime = 0; 190 s->runTime = RUN_TIME; 191 s->thread_id = i;//编号令为0 192 s->Finished = false; 193 s->next = NULL; 194 //尾插入 195 if (!pool->tcb)//第一个节点 196 { 197 pool->tcb = s; 198 } 199 else 200 { 201 ptemp = pool->tcb; 202 while (ptemp && ptemp->next) 203 { 204 ptemp = ptemp->next; 205 } 206 ptemp->next = s; 207 } 208 } 209 //初始化信号量 210 ptemp = pool->tcb; 211 int i = 0; 212 while (ptemp) 213 { 214 int i = ptemp->thread_id; 215 sem_init(&(pool->sem[i]), 0, 0); 216 ptemp = ptemp->next; 217 } 218 //创建线程 219 ptemp = pool->tcb; 220 pool->threadid = (pthread_t*)malloc(sizeof(pthread_t) * (THREAD_MAXN+1)); 221 while (ptemp) 222 { 223 //把ptemp作为参数传入thread_run_func() 224 int t; 225 t = pthread_create(&(pool->threadid[ptemp->thread_id]), \ 226 NULL, thread_run_func, ptemp); 227 if (!t)//线程创建成功 228 { 229 printf("线程%d创建成功!\n", ptemp->thread_id); 230 } 231 else 232 { 233 printf("线程创建失败!\n"); 234 } 235 ptemp = ptemp->next; 236 } 237 printf("线程池pool初始化完成!\n"); 238 } 239 void* thread_run_func(void* param)//线程里运行的函数 240 { 241 TCB* ptemp = (TCB*)param; 242 while (ptemp->runTime > 0) 243 { 244 sem_wait(&(pool->sem[ptemp->thread_id]));//唤醒 245 pthread_mutex_lock(&(pool->tcb_lock));//上互斥锁 246 if (pool->fDestroyed) 247 { 248 pthread_mutex_unlock(&(pool->tcb_lock)); 249 printf ("线程%d退出\n", ptemp->thread_id); 250 pthread_exit (NULL); 251 } 252 ptemp->runTime -= RUNTIME_SUB; 253 if(ptemp->runTime > 0) enqueue(&(pool->rrQueue), ptemp); 254 printf("线程%d(剩余时间%d->%d)", ptemp->thread_id, ptemp->runTime + RUNTIME_SUB, ptemp->runTime < 0 ? 0 : ptemp->runTime); 255 //线程操作 256 struct task *pTask = pool->task_queue; 257 if(pool->task_queue) 258 { 259 pool->task_queue = pool->task_queue->next; 260 --pool->task_num; 261 } 262 else 263 { 264 pthread_mutex_unlock(&(pool->tcb_lock)); 265 printf("任务为空\n"); 266 break; 267 } 268 (*(pTask->task_func))(pTask->param); 269 free(pTask); 270 pTask = NULL; 271 pthread_mutex_unlock(&(pool->tcb_lock)); 272 sleep(1); 273 } 274 pthread_exit(NULL); 275 } 276 void round_robin()//时间片轮转算法的调度函数 277 { 278 TCB* ptemp = pool->tcb; 279 while (1) 280 { 281 ++nowTime; 282 pthread_mutex_lock(&(pool->tcb_lock)); 283 if (pool->nFinish == THREAD_MAXN)//所有线程完成 284 break; 285 while (ptemp && ptemp->arriveTime == nowTime) 286 { 287 printf("当前时间为%d, 线程%d进入轮转队列,运行时间:%d\n",nowTime, ptemp->thread_id, ptemp->runTime); 288 enqueue(&(pool->rrQueue), ptemp); 289 ptemp=ptemp->next; 290 } 291 printf("\n"); 292 show_rr(); 293 pull_thread(); 294 pthread_mutex_unlock(&(pool->tcb_lock)); 295 sleep(10); 296 if(!pool->task_queue)break; 297 } 298 } 299 int pool_destroy()//销毁线程池 300 { 301 if (pool->fDestroyed)//防止重复销毁 302 return -1; 303 pool->fDestroyed = 1; 304 TCB* ptemp = pool->tcb; 305 while (ptemp) 306 { 307 pthread_join(pool->threadid[ptemp->thread_id], NULL); 308 printf("线程%d已结束\n", ptemp->thread_id); 309 ptemp = ptemp->next; 310 } 311 struct task *ptask = pool->task_queue; 312 while (pool->task_queue) 313 { 314 ptask = pool->task_queue; 315 pool->task_queue = pool->task_queue->next; 316 free(ptask); 317 } 318 free(ptemp); 319 free(pool->threadid); 320 pthread_mutex_destroy(&(pool->tcb_lock)); 321 free(pool); 322 pool = NULL; 323 printf("线程池pool已被销毁!\n"); 324 return 0; 325 } 326 void* task_run() 327 { 328 printf("正在执行任务\n"); 329 sleep(1); 330 return; 331 } 332 void add_task(void *(*task_func)(void *param)) 333 { 334 pthread_mutex_lock(&(pool->tcb_lock)); 335 struct task *newtask = (struct task*) malloc (sizeof (struct task)); 336 newtask->task_func = task_run;//要执行的函数 337 newtask->next = NULL; 338 struct task *pTask = pool->task_queue; 339 if (pTask) 340 { 341 while (pTask && pTask->next) 342 pTask = pTask->next; 343 pTask->next = newtask; 344 } 345 else 346 { 347 pool->task_queue = newtask; 348 } 349 ++pool->task_num; 350 pthread_mutex_unlock(&(pool->tcb_lock)); 351 return; 352 } 353 void task_init() 354 { 355 for(int i = 0; i < TASK_NUM; ++i) 356 add_task(task_run); 357 } 358 void pull_thread() 359 { 360 struct TCB *ptemp1 = NULL; 361 struct TCB *ptemp2 = NULL; 362 struct TCB *ptemp3 = NULL; 363 if(pool->nowPullQueue) 364 { 365 struct nowPullQueue *ppull = pool->nowPullQueue; 366 while(pool->nowPullQueue) 367 { 368 ppull = pool->nowPullQueue; 369 pool->nowPullQueue = pool->nowPullQueue->next; 370 free(ppull); 371 } 372 pool->nowPullQueue = NULL; 373 } 374 printf("当前时间为:%d,轮转的线程为:",nowTime); 375 if(!empty(&(pool->rrQueue))) 376 { 377 ptemp1 = dequeue(&(pool->rrQueue)); 378 sem_post(&(pool->sem[ptemp1->thread_id])); 379 insert_counterpart(ptemp1); 380 sleep(2); 381 if(!empty(&(pool->rrQueue))) 382 { 383 ptemp2 = dequeue(&(pool->rrQueue)); 384 sem_post(&(pool->sem[ptemp2->thread_id])); 385 insert_counterpart(ptemp2); 386 sleep(2); 387 if(!empty(&(pool->rrQueue))) 388 { 389 ptemp3 = dequeue(&(pool->rrQueue)); 390 sem_post(&(pool->sem[ptemp3->thread_id])); 391 insert_counterpart(ptemp3); 392 sleep(2); 393 } 394 } 395 } 396 printf("\n"); 397 } 398 void enqueue(struct tcb_queue *q, struct TCB* tcb) 399 { 400 q->r = (q->r + 1) % (THREAD_MAXN+1); 401 q->tcbQueue[q->r] = tcb; 402 } 403 struct TCB* dequeue(struct tcb_queue *q) 404 { 405 q->f = (q->f + 1) % (THREAD_MAXN+1); 406 return q->tcbQueue[q->f]; 407 } 408 struct TCB* get_front(struct tcb_queue *q) 409 { 410 return q->tcbQueue[(q->f + 1) % (THREAD_MAXN+1)]; 411 } 412 bool empty(struct tcb_queue *q) 413 { 414 return q->r == q->f; 415 } 416 struct TCB_counterpart* create_TCB_counterpart() 417 { 418 struct TCB_counterpart *s = (struct TCB_counterpart*)malloc(sizeof(struct TCB_counterpart)); 419 s->next = NULL; 420 s->father = NULL; 421 return s; 422 } 423 void insert_counterpart(struct TCB *tcb) 424 { 425 if(!pool->nowPullQueue) 426 { 427 pool->nowPullQueue = create_TCB_counterpart(); 428 pool->nowPullQueue->father = tcb; 429 } 430 else 431 { 432 struct TCB_counterpart *ptemp = pool->nowPullQueue; 433 while(ptemp && ptemp->next) 434 { 435 ptemp = ptemp->next; 436 } 437 ptemp->next = create_TCB_counterpart(); 438 ptemp->next->father = tcb; 439 } 440 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <semaphore.h> 5 #include <unistd.h> 6 #include <time.h> 7 #include <sys/types.h> 8 #include <pthread.h> 9 #define bool int 10 #define true 1 11 #define false 0 12 #define rerange BF_rerange//选择内存分配方法 13 #define schedule fifo//选择调度方法 14 #define THREAD_MAXN 2//线程数 15 #define RUNTIME_SUB 1//每次运行线程减去的运行时间 16 #define INIT_FREE_BLOCK_NUM 8//内存块初始数量 17 #define INIT_FREE_BLOCK_SIZE 10//内存块初始大小 18 #define FREE_MAXN 80//最大空闲块数量 19 #define RUN_TIME 10000//线程运行时间 20 #define STU_NUM 10000//学生数量 21 //-----结构体定义 22 typedef struct TCB//存储线程信息 23 { 24 int thread_id;//线程编号 25 int arriveTime;//线程到达时间 26 int runTime;//持续时间 27 int finishTime;//完成时间 28 int wholeTime;//周转时间 29 double weightWholeTime;//带权周转时间 30 bool Finished;//线程是否完成 31 struct TCB* next;//使用链式存储方式 32 }TCB; 33 struct task 34 { 35 void *(*task_func) (void *param); 36 void *param; 37 struct task *next; 38 }; 39 struct tcb_queue//TCB队列定义 40 { 41 struct TCB* tcbQueue[THREAD_MAXN+1];//TCB指针数组 42 int r, f; 43 }; 44 struct thread_pool//线程池结构体 45 { 46 pthread_mutex_t tcb_lock;//互斥锁 47 int fDestroyed;//线程池是否被销毁 48 pthread_t* threadid;//存储线程标识符指针 49 struct TCB* nowRunThread;//指向当前正在运行的线程 50 int nFinish;//完成线程数 51 sem_t sem[THREAD_MAXN+1];//用于控制线程的信号量 52 struct tcb_queue rrQueue;//轮转队列 53 struct tcb_queue showQueue;//用于辅助打印的队列 54 struct task *task_queue;//任务队列 55 int task_num; 56 struct TCB* tcb;//存储TCB 57 }; 58 struct free_block//空闲块结构体 59 { 60 int start;//起始位置 61 int size; 62 struct free_block* next; 63 }; 64 struct busy_block//被分配的内存块 65 { 66 int id;//编号 67 int start; 68 int size; 69 char* data;//根据需要动态分配 70 struct busy_block* next; 71 }; 72 struct student//储存学生信息 73 { 74 char number[9]; 75 char name[76]; 76 int name_size; 77 }; 78 //-----全局变量定义 79 static struct thread_pool* pool = NULL;//全局变量pool,指向线程池 80 int nowTime;//当前已走过的时间 81 int busy_cnt = -1;//分配块编号计数器 82 int nFree = 0;//空闲块数量 83 int nBusy = 0;//已分配块数量 84 int nameCnt = 0;//名字存储计数器 85 int numCnt = 0;//学号存储计数器 86 int ScheduleCnt = 0;//调度次数 87 struct free_block* free_queue = NULL;//储存空闲块的链表 88 struct busy_block* busy_queue = NULL;//储存已分配块的链表 89 struct student student_info[STU_NUM]; 90 //-----函数声明 91 void TCB_bubble();//给TCB排序 92 void add_task (void *(*task_func)(void *param)); 93 void show_rr();//打印轮转队列 94 void show_tcb();//打印所有线程的信息 95 void pool_init();//初始化线程池 96 void* thread_run_func(void* param);//线程里运行的函数 97 void round_robin();//时间片轮转算法的调度函数 98 int pool_destroy();//销毁线程池 99 void init_free();//初始化空闲块 100 struct free_block* create_free(int start, int size, struct free_block* next);//创建一个空闲块 101 struct busy_block* create_busy(int start, int size, struct busy_block* next, char* data);//创建一个已分配块 102 struct free_block* merge_free(struct free_block* f);//合并所有能够合并的空闲内存块 103 void init_student();//初始化学生的学号,姓名,采用随机生成的方法 104 void insert_busy(struct busy_block* pBusy);//尾插法插入一个分配块到链表busy_queue中 105 void insert_free(struct free_block* pFree);//尾插法插入一个空闲块到链表free_queue中 106 void delete_free(struct free_block* pFree, int size);//删除一个空闲块中被占用的部分,保留剩余部分 107 void fifo_delete_busy();//fifo算法中删除分配块 108 void lifo_delete_busy();//lifo算法中删除分配块 109 void show_free();//显示空闲块链表 110 void show_busy();//显示分配块链表 111 void free_bubble(int choice);//choice1:start升序,choice2:size升序,choice3:size降序 112 void FF_rerange();//按不同内存分配方法的规则排序 113 void BF_rerange(); 114 void WF_rerange(); 115 void *store_info(void* param);//param: 1存学号,2存姓名 116 void merge_in();//合并空闲内存块函数的入口 117 void fifo();//fifo算法调出分配块 118 void lifo();//lifo算法调出分配块 119 void enqueue(struct tcb_queue *q, struct TCB* tcb); 120 struct TCB* dequeue(struct tcb_queue *q); 121 struct TCB* get_front(struct tcb_queue *q); 122 bool empty(struct tcb_queue *q); 123 //main 124 int main() 125 { 126 init_student(); 127 init_free(); 128 pool_init(); 129 TCB_bubble(); 130 show_tcb(); 131 for(int i = 0; i < 2*STU_NUM; ++i) add_task(store_info); 132 round_robin(); 133 sleep(3); 134 pool_destroy(); 135 return 0; 136 } 137 //函数定义 138 void TCB_bubble()//给TCB排序,按arriveTime升序排列 139 { 140 TCB* ptemp = NULL; 141 for (int i = 0; i < THREAD_MAXN+1; ++i) 142 { 143 ptemp = pool->tcb; 144 int f = 0; 145 while (ptemp && ptemp->next) 146 { 147 if (ptemp->arriveTime > ptemp->next->arriveTime) 148 {//交换两个节点 149 f = 1; 150 TCB* p_next = ptemp->next->next; 151 TCB* p_pre = ptemp;//后面ptemp = ptemp->next,当前ptemp相当于pre 152 TCB* p_pre_pre = pool->tcb;//pre的pre 153 if (p_pre_pre == p_pre)//说明ptemp是头结点 154 { 155 p_pre_pre = NULL; 156 } 157 else//否则找到pre_pre所在位置 158 { 159 while (p_pre_pre && p_pre_pre->next != p_pre) 160 { 161 p_pre_pre = p_pre_pre->next; 162 } 163 } 164 //交换结点 165 ptemp = ptemp->next; 166 ptemp->next = p_pre; 167 p_pre->next = p_next; 168 if (p_pre_pre) 169 { 170 p_pre_pre->next = ptemp; 171 } 172 else 173 { 174 pool->tcb = ptemp; 175 } 176 } 177 ptemp = ptemp->next; 178 } 179 if(f == 0) return; 180 } 181 } 182 void show_rr()//打印轮转队列 183 { 184 printf("当前时间为:%d\n", nowTime); 185 if (pool->rrQueue.f == pool->rrQueue.r) 186 { 187 printf("目前还没有线程到达\n"); 188 } 189 else 190 { 191 printf("目前轮转队列为:\n"); 192 } 193 while (!empty(&(pool->rrQueue))) 194 { 195 enqueue(&(pool->showQueue), get_front(&(pool->rrQueue))); 196 printf("%d ", dequeue(&(pool->rrQueue))->thread_id); 197 } 198 while (!empty(&(pool->showQueue)))//将队列放回 199 { 200 enqueue(&(pool->rrQueue), dequeue(&(pool->showQueue))); 201 } 202 printf("\n\n"); 203 } 204 void show_tcb()//打印所有线程的信息 205 { 206 TCB* ptemp = pool->tcb; 207 printf("打印所有线程的信息:\n"); 208 while (ptemp) 209 { 210 printf("线程%d:到达时间:%d,剩余时间:%d\n", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime); 211 ptemp = ptemp->next; 212 } 213 printf("\n"); 214 } 215 void pool_init()//初始化线程池 216 { 217 pool = (struct thread_pool*)malloc(sizeof(struct thread_pool)); 218 pthread_mutex_init(&(pool->tcb_lock), NULL);//初始为未锁住状态 219 pool->fDestroyed = 0;//线程池是否被销毁 220 pool->nFinish = 0; 221 pool->task_num = 0; 222 pool->nowRunThread = NULL;//指向当前正在运行的线程 223 pool->rrQueue.f = pool->rrQueue.r = 0;//轮转队列 224 pool->showQueue.r = pool->showQueue.r = 0;//用于辅助打印的队列 225 pool->task_queue = NULL; 226 pool->tcb = NULL; 227 //创建并初始化TCB 228 TCB* ptemp = pool->tcb; 229 srand(time(0)); 230 for (int i = 0; i < THREAD_MAXN; ++i) 231 { 232 TCB* s = (TCB*)malloc(sizeof(TCB)); 233 // s->arriveTime = rand()%9; 234 s->arriveTime = 0; 235 s->runTime = RUN_TIME; 236 s->thread_id = i;//编号令为0 237 s->Finished = false; 238 s->next = NULL; 239 //尾插入 240 if (!pool->tcb)//第一个节点 241 { 242 pool->tcb = s; 243 } 244 else 245 { 246 ptemp = pool->tcb; 247 while (ptemp && ptemp->next) 248 { 249 ptemp = ptemp->next; 250 } 251 ptemp->next = s; 252 } 253 } 254 //初始化信号量 255 ptemp = pool->tcb; 256 int i = 0; 257 while (ptemp) 258 { 259 int i = ptemp->thread_id; 260 sem_init(&(pool->sem[i]), 0, 0); 261 ptemp = ptemp->next; 262 } 263 //创建线程 264 ptemp = pool->tcb; 265 pool->threadid = (pthread_t*)malloc(sizeof(pthread_t) * (THREAD_MAXN+1)); 266 while (ptemp) 267 { 268 //把ptemp作为参数传入thread_run_func() 269 int t; 270 t = pthread_create(&(pool->threadid[ptemp->thread_id]), \ 271 NULL, thread_run_func, ptemp); 272 if (!t)//线程创建成功 273 { 274 printf("线程%d创建成功!\n", ptemp->thread_id); 275 } 276 else 277 { 278 printf("线程创建失败!\n"); 279 } 280 ptemp = ptemp->next; 281 } 282 printf("线程池pool初始化完成!\n"); 283 } 284 void* thread_run_func(void* param)//线程里运行的函数 285 { 286 TCB* ptemp = (TCB*)param; 287 int i = 0; 288 while (ptemp->runTime > 0) 289 { 290 sem_wait(&(pool->sem[ptemp->thread_id]));//唤醒 291 pthread_mutex_lock(&(pool->tcb_lock));//上互斥锁 292 if (pool->fDestroyed) 293 { 294 pthread_mutex_unlock(&(pool->tcb_lock)); 295 printf ("线程%d退出\n", ptemp->thread_id); 296 pthread_exit (NULL); 297 } 298 ptemp->runTime -= RUNTIME_SUB; 299 //线程操作 300 printf("当前线程:%d号\n", ptemp->thread_id); 301 struct task *pTask = pool->task_queue; 302 if(pool->task_queue) 303 { 304 pool->task_queue = pool->task_queue->next; 305 --pool->task_num; 306 } 307 else 308 { 309 pthread_mutex_unlock(&(pool->tcb_lock)); 310 printf("任务为空\n"); 311 break; 312 } 313 if (ptemp->thread_id == 0)i = 1;//number 314 else i = 2; 315 (*(pTask->task_func))(&i); 316 317 free(pTask); 318 pTask = NULL; 319 //线程操作 320 if (ptemp->runTime <= 0)//线程已经完成 321 { 322 ++pool->nFinish; 323 ptemp->Finished = true; 324 //出队 325 dequeue(&(pool->rrQueue)); 326 } 327 else 328 {//还未完成 329 //出队 330 dequeue(&(pool->rrQueue)); 331 //入队 332 enqueue(&(pool->rrQueue), ptemp); 333 } 334 pthread_mutex_unlock(&(pool->tcb_lock)); 335 sleep(1); 336 } 337 pthread_exit(NULL); 338 } 339 void round_robin()//时间片轮转算法的调度函数 340 { 341 TCB* ptemp = pool->tcb; 342 while (1) 343 { 344 //sleep(1); 345 pthread_mutex_lock(&(pool->tcb_lock)); 346 if (pool->nFinish == THREAD_MAXN)//所有线程完成 347 break; 348 while (ptemp && ptemp->arriveTime == nowTime) 349 { 350 enqueue(&(pool->rrQueue), ptemp); 351 ptemp = ptemp->next; 352 } 353 if (pool->rrQueue.f != pool->rrQueue.r) 354 { 355 pool->nowRunThread = get_front(&(pool->rrQueue)); 356 sem_post(&(pool->sem[pool->nowRunThread->thread_id])); 357 } 358 ++nowTime; 359 pthread_mutex_unlock(&(pool->tcb_lock)); 360 sleep(1); 361 } 362 } 363 int pool_destroy()//销毁线程池 364 { 365 if (pool->fDestroyed)//防止重复销毁 366 return -1; 367 pool->fDestroyed = 1; 368 TCB* ptemp = pool->tcb; 369 while (ptemp) 370 { 371 pthread_join(pool->threadid[ptemp->thread_id], NULL); 372 printf("线程%d已结束\n", ptemp->thread_id); 373 ptemp = ptemp->next; 374 } 375 free(ptemp); 376 free(pool->threadid); 377 pthread_mutex_destroy(&(pool->tcb_lock)); 378 free(pool); 379 pool = NULL; 380 printf("线程池pool已被销毁!\n"); 381 return 0; 382 } 383 384 //---------------------------------------------------------------------------------- 385 386 void init_free() 387 { 388 int start_address = 0; 389 struct free_block* ptemp = NULL; 390 for (int i = 0; i < INIT_FREE_BLOCK_NUM; ++i) 391 { 392 struct free_block* s = create_free(start_address, INIT_FREE_BLOCK_SIZE, NULL); 393 printf("已创建起始地址为%d,大小为%d的空闲块!\n", s->start, s->size); 394 ++nFree; 395 if (!free_queue) 396 { 397 free_queue = s; 398 } 399 else 400 { 401 ptemp = free_queue; 402 while (ptemp && ptemp->next) 403 { 404 ptemp = ptemp->next; 405 } 406 ptemp->next = s; 407 } 408 start_address += INIT_FREE_BLOCK_SIZE; 409 } 410 printf("空闲内存块初始化完成!\n"); 411 show_free(); 412 } 413 struct free_block* create_free(int start, int size, struct free_block* next) 414 { 415 struct free_block* s = (struct free_block*)malloc(sizeof(struct free_block)); 416 s->start = start; 417 s->size = size; 418 s->next = next; 419 return s; 420 } 421 struct busy_block* create_busy(int start, int size, struct busy_block* next, char* data) 422 { 423 struct busy_block* s = (struct busy_block*)malloc(sizeof(struct busy_block)); 424 s->start = start; 425 s->id = ++busy_cnt; 426 s->next = NULL; 427 s->size = size; 428 s->data = (char*)malloc(sizeof(char) * size); 429 for (int i = 0; i < size; ++i) 430 { 431 s->data[i] = data[i]; 432 } 433 return s; 434 } 435 void init_student() 436 { 437 srand(time(0)); 438 for (int i = 0; i < STU_NUM; ++i) 439 { 440 strcpy(student_info[i].number, "18"); 441 for(int j=2; j<8; ++j) 442 { 443 student_info[i].number[j] = (char)('0'+(rand()%10)); 444 } 445 student_info[i].number[8] = '\0'; 446 student_info[i].name_size = 4 + (rand() % 70);//拼音长度:4~20 447 for (int j = 0; j < student_info[i].name_size; ++j) 448 { 449 student_info[i].name[j] = (char)('a' + rand()%26); 450 } 451 student_info[i].name[student_info[i].name_size] = '\0'; 452 printf("编号:%d,姓名:%s,姓名大小:%d,学号:%s\n", i, student_info[i].name, student_info[i].name_size, student_info[i].number); 453 } 454 printf("学生信息初始化完成!\n"); 455 } 456 void free_bubble(int choice) 457 { 458 struct free_block* ptemp = NULL; 459 if (free_queue) 460 for (int i = 0; i < FREE_MAXN; ++i) 461 { 462 int fReturn = 0; 463 ptemp = free_queue; 464 while (ptemp && ptemp->next) 465 { 466 if ((ptemp->start > ptemp->next->start && choice == 1) || /*FF*/ 467 (ptemp->size > ptemp->next->size && choice == 2) || /*BF*/ 468 (ptemp->size < ptemp->next->size && choice == 3) ) /*WF*/ 469 {//交换两个节点 470 fReturn = 1; 471 struct free_block* p_next = ptemp->next->next; 472 struct free_block* p_pre = ptemp; 473 struct free_block* p_pre_pre = free_queue; 474 if (p_pre_pre == p_pre) 475 { 476 p_pre_pre = NULL; 477 } 478 else 479 { 480 while (p_pre_pre && p_pre_pre->next != p_pre) 481 { 482 p_pre_pre = p_pre_pre->next; 483 } 484 } 485 ptemp = ptemp->next; 486 ptemp->next = p_pre; 487 p_pre->next = p_next; 488 if (p_pre_pre) 489 { 490 p_pre_pre->next = ptemp; 491 } 492 else 493 { 494 free_queue = ptemp; 495 } 496 } 497 ptemp = ptemp->next; 498 } 499 if(fReturn == 0)//排序已完成 500 { 501 return; 502 } 503 } 504 } 505 void insert_busy(struct busy_block* pBusy) 506 { 507 if (!busy_queue) 508 { 509 busy_queue = pBusy; 510 } 511 else 512 { 513 struct busy_block* ptemp = busy_queue; 514 while (ptemp && ptemp->next) 515 { 516 ptemp = ptemp->next; 517 } 518 ptemp->next = pBusy; 519 } 520 ++nBusy; 521 printf("完成插入分配块——开始地址:%d,大小:%d\n", pBusy->start, pBusy->size); 522 return; 523 } 524 void insert_free(struct free_block* pFree) 525 { 526 if (!free_queue) 527 { 528 free_queue = pFree; 529 } 530 else 531 { 532 struct free_block* ptemp = free_queue; 533 while (ptemp && ptemp->next) 534 { 535 ptemp = ptemp->next; 536 } 537 ptemp->next = pFree; 538 } 539 ++nFree; 540 printf("完成插入空闲块——开始地址:%d,大小:%d\n", pFree->start, pFree->size); 541 return; 542 } 543 void delete_free(struct free_block* pFree, int size) 544 { 545 if (!free_queue)return; 546 struct free_block* ptemp = free_queue; 547 struct free_block* pre = NULL; 548 while (ptemp) 549 { 550 if (ptemp == pFree) 551 { 552 if (pre) 553 { 554 if (pFree->size == size)//无剩余 555 { 556 --nFree; 557 pre->next = ptemp->next; 558 } 559 else 560 { 561 pre->next = create_free(pFree->start + size, pFree->size - size, ptemp->next); 562 } 563 } 564 else 565 { 566 if (pFree->size == size) 567 { 568 free_queue = ptemp->next; 569 } 570 else 571 { 572 free_queue = create_free(pFree->start + size, pFree->size - size, ptemp->next); 573 } 574 } 575 free(ptemp); 576 ptemp = NULL; 577 break; 578 } 579 pre = ptemp; 580 ptemp = ptemp->next; 581 } 582 return; 583 } 584 void fifo_delete_busy() 585 { 586 if (busy_queue) 587 { 588 struct busy_block* ptemp = busy_queue; 589 busy_queue = busy_queue->next; 590 free(ptemp); 591 ptemp = NULL; 592 --nBusy; 593 } 594 else 595 { 596 printf("无分配块\n"); 597 } 598 } 599 void lifo_delete_busy() 600 { 601 if (busy_queue) 602 { 603 struct busy_block* ptemp = busy_queue; 604 struct busy_block* pre = NULL; 605 while (ptemp && ptemp->next) 606 { 607 pre = ptemp; 608 ptemp = ptemp->next; 609 } 610 if (!pre) 611 { 612 busy_queue = NULL; 613 } 614 else 615 { 616 pre->next = NULL; 617 } 618 free(ptemp); 619 ptemp = NULL; 620 --nBusy; 621 } 622 else 623 { 624 printf("无分配块\n"); 625 } 626 return; 627 } 628 void show_free() 629 { 630 if (free_queue) 631 { 632 struct free_block* ptemp = free_queue; 633 printf("显示空闲块:\n"); 634 while (ptemp) 635 { 636 printf("————开始:%d,大小:%d\n", ptemp->start, ptemp->size); 637 ptemp = ptemp->next; 638 } 639 printf("\n"); 640 } 641 else 642 { 643 printf("当前无空闲块\n"); 644 } 645 return; 646 } 647 void show_busy() 648 { 649 if (busy_queue) 650 { 651 struct busy_block* ptemp = busy_queue; 652 printf("显示已分配块:\n"); 653 while (ptemp) 654 { 655 printf("—————————序号:%d,开始:%d,大小:%d,数据:", ptemp->id, ptemp->start, ptemp->size); 656 for (int i = 0; i < ptemp->size; ++i) 657 { 658 printf("%c", ptemp->data[i]); 659 } 660 printf("\n"); 661 ptemp = ptemp->next; 662 } 663 printf("\n"); 664 } 665 else 666 { 667 printf("当前无分配块\n"); 668 } 669 return; 670 } 671 void merge_in() 672 { 673 free_bubble(1); 674 free_queue = merge_free(free_queue); 675 printf("紧缩完成\n"); 676 return; 677 } 678 struct free_block* merge_free(struct free_block* f) 679 { 680 if (f && f->next) 681 { 682 f->next = merge_free(f->next); 683 if (f->next && (f->start + f->size == f->next->start)) 684 { 685 struct free_block* p = f->next; 686 f->next = p->next; 687 f->size += p->size; 688 free(p); 689 p = NULL; 690 } 691 } 692 return f; 693 } 694 void fifo() 695 { 696 if (busy_queue) 697 { 698 printf("+++++++++++++++++++++被调出的信息:序号:%d,开始地址:%d,大小:%d, 数据:", \ 699 busy_queue->id, busy_queue->start, busy_queue->size); 700 for (int k = 0; k < busy_queue->size; ++k) 701 { 702 printf("%c", busy_queue->data[k]); 703 } 704 printf("\n"); 705 printf("+++++++++++++++++++++调度次数:%d\n", ++ScheduleCnt); 706 struct free_block* pFree = create_free(busy_queue->start, busy_queue->size, NULL); 707 insert_free(pFree); 708 fifo_delete_busy(); 709 } 710 else 711 { 712 printf("无分配块,无法调出\n"); 713 } 714 return; 715 } 716 void lifo() 717 { 718 if (busy_queue) 719 { 720 struct busy_block* ptemp = busy_queue; 721 while (ptemp && ptemp->next) 722 { 723 ptemp = ptemp->next; 724 } 725 printf("+++++++++++++++++++++被调出的信息:序号:%d,开始地址:%d,大小:%d, 数据:", \ 726 ptemp->id, ptemp->start, ptemp->size); 727 for (int k = 0; k < ptemp->size; ++k) 728 { 729 printf("%c", ptemp->data[k]); 730 } 731 printf("\n"); 732 printf("+++++++++++++++++++++调度次数:%d\n", ++ScheduleCnt); 733 struct free_block* pFree = create_free(ptemp->start, ptemp->size, NULL); 734 insert_free(pFree); 735 lifo_delete_busy(); 736 } 737 else 738 { 739 printf("无分配块,无法调出\n"); 740 } 741 return; 742 } 743 void FF_rerange() 744 { 745 merge_in(); 746 return; 747 } 748 void BF_rerange() 749 { 750 merge_in(); 751 free_bubble(2); 752 return; 753 } 754 void WF_rerange() 755 { 756 merge_in(); 757 free_bubble(3); 758 return; 759 } 760 void *store_info(void* param) 761 { 762 int choice = *((int*)param); 763 struct free_block* pFree = free_queue; 764 struct busy_block* pBusy = busy_queue; 765 int subscript = choice == 1 ? numCnt : nameCnt; 766 char *data = choice == 1 ? student_info[subscript].number : student_info[subscript].name; 767 int size = choice == 1 ? 8 : student_info[subscript].name_size; 768 printf("将要放入内存的信息:"); 769 for (int c = 0; c < size; ++c) 770 { 771 printf("%c", data[c]); 772 } 773 printf(",大小:%d\n", size); 774 printf("将所有空闲内存块紧缩\n"); 775 rerange(); 776 show_free(); 777 int fEnough = 0;//内存大小是否足够 778 while (!fEnough) 779 { 780 if (pFree && pFree->size >= size) 781 { 782 fEnough = 1; 783 if(choice == 1) ++numCnt; 784 else ++nameCnt; 785 pBusy = create_busy(pFree->start, size, NULL, data); 786 printf("正在存储的信息:开始地址:%d, 大小:%d\n", pFree->start, size); 787 delete_free(pFree, size); 788 insert_busy(pBusy); 789 show_busy(); 790 break; 791 } 792 else 793 { 794 if (pFree) 795 { 796 printf("当前指向空闲内存大小不够,跳到下一块空闲内存\n"); 797 pFree = pFree->next; 798 } 799 else 800 { 801 printf("没有足够大小的空闲内存可用,开始调度:\n"); 802 schedule(); 803 printf("将所有空闲内存块紧缩并排序\n"); 804 rerange(); 805 show_free(); 806 pFree = free_queue; 807 } 808 } 809 } 810 sleep(1); 811 } 812 void add_task (void *(*task_func)(void *param)) 813 { 814 struct task *newtask = (struct task*) malloc (sizeof (struct task)); 815 pthread_mutex_lock(&(pool->tcb_lock)); 816 newtask->task_func = store_info;//要执行的函数 817 newtask->next = NULL; 818 struct task *pTask = pool->task_queue; 819 if (pTask) 820 { 821 while (pTask && pTask->next) 822 pTask = pTask->next; 823 pTask->next = newtask; 824 } 825 else 826 { 827 pool->task_queue = newtask; 828 } 829 ++pool->task_num; 830 pthread_mutex_unlock(&(pool->tcb_lock)); 831 return; 832 } 833 void enqueue(struct tcb_queue *q, struct TCB* tcb) 834 { 835 q->r = (q->r + 1) % (THREAD_MAXN+1); 836 q->tcbQueue[q->r] = tcb; 837 } 838 struct TCB* dequeue(struct tcb_queue *q) 839 { 840 q->f = (q->f + 1) % (THREAD_MAXN+1); 841 return q->tcbQueue[q->f]; 842 } 843 struct TCB* get_front(struct tcb_queue *q) 844 { 845 return q->tcbQueue[(q->f + 1) % (THREAD_MAXN+1)]; 846 } 847 bool empty(struct tcb_queue *q) 848 { 849 return q->r == q->f; 850 }