zoukankan      html  css  js  c++  java
  • 线程池+时间片轮转法调度+连续内存管理+内存调度

      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("目前还没有线程在队列中
    ");
    142     }
    143     else
    144     {
    145         printf("目前轮转队列为:
    ");
    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("
    ");
    157 }
    158 void show_tcb()//打印所有线程的信息
    159 {
    160     TCB* ptemp = pool->tcb;
    161     printf("打印所有线程的信息:
    ");
    162     while (ptemp)
    163     {
    164         printf("线程%d:到达时间:%d,剩余时间:%d
    ", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime);
    165         ptemp = ptemp->next;
    166     }
    167     printf("
    ");
    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创建成功!
    ", ptemp->thread_id);
    230         }
    231         else
    232         {
    233             printf("线程创建失败!
    ");
    234         }
    235         ptemp = ptemp->next;
    236     }
    237     printf("线程池pool初始化完成!
    ");
    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退出
    ", 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("任务为空
    ");
    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
    ",nowTime, ptemp->thread_id, ptemp->runTime);
    288             enqueue(&(pool->rrQueue), ptemp);
    289             ptemp=ptemp->next;
    290         }
    291         printf("
    ");
    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已结束
    ", 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已被销毁!
    ");
    324     return 0;
    325 }
    326 void* task_run()
    327 {
    328     printf("正在执行任务
    ");
    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("
    ");
    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
    ", nowTime);
    185     if (pool->rrQueue.f == pool->rrQueue.r)
    186     {
    187         printf("目前还没有线程到达
    ");
    188     }
    189     else
    190     {
    191         printf("目前轮转队列为:
    ");
    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("
    
    ");
    203 }
    204 void show_tcb()//打印所有线程的信息
    205 {
    206     TCB* ptemp = pool->tcb;
    207     printf("打印所有线程的信息:
    ");
    208     while (ptemp)
    209     {
    210         printf("线程%d:到达时间:%d,剩余时间:%d
    ", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime);
    211         ptemp = ptemp->next;
    212     }
    213     printf("
    ");
    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创建成功!
    ", ptemp->thread_id);
    275         }
    276         else
    277         {
    278             printf("线程创建失败!
    ");
    279         }
    280         ptemp = ptemp->next;
    281     }
    282     printf("线程池pool初始化完成!
    ");
    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退出
    ", ptemp->thread_id);
    296             pthread_exit (NULL);
    297         }
    298         ptemp->runTime -= RUNTIME_SUB;
    299         //线程操作
    300         printf("当前线程:%d号
    ", 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("任务为空
    ");
    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已结束
    ", 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已被销毁!
    ");
    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的空闲块!
    ", 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("空闲内存块初始化完成!
    ");
    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] = '';
    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] = '';
    452         printf("编号:%d,姓名:%s,姓名大小:%d,学号:%s
    ", i, student_info[i].name, student_info[i].name_size, student_info[i].number);
    453     }
    454     printf("学生信息初始化完成!
    ");
    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
    ", 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
    ", 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("无分配块
    ");
    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("无分配块
    ");
    625     }
    626     return;
    627 }
    628 void show_free()
    629 {
    630     if (free_queue)
    631     {
    632         struct free_block* ptemp = free_queue;
    633         printf("显示空闲块:
    ");
    634         while (ptemp)
    635         {
    636             printf("————开始:%d,大小:%d
    ", ptemp->start, ptemp->size);
    637             ptemp = ptemp->next;
    638         }
    639         printf("
    ");
    640     }
    641     else
    642     {
    643         printf("当前无空闲块
    ");
    644     }
    645     return;
    646 }
    647 void show_busy()
    648 {
    649     if (busy_queue)
    650     {
    651         struct busy_block* ptemp = busy_queue;
    652         printf("显示已分配块:
    ");
    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("
    ");
    661             ptemp = ptemp->next;
    662         }
    663         printf("
    ");
    664     }
    665     else
    666     {
    667         printf("当前无分配块
    ");
    668     }
    669     return;
    670 }
    671 void merge_in()
    672 {
    673     free_bubble(1);
    674     free_queue = merge_free(free_queue);
    675     printf("紧缩完成
    ");
    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("
    ");
    705         printf("+++++++++++++++++++++调度次数:%d
    ", ++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("无分配块,无法调出
    ");
    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("
    ");
    732         printf("+++++++++++++++++++++调度次数:%d
    ", ++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("无分配块,无法调出
    ");
    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
    ", size);
    774     printf("将所有空闲内存块紧缩
    ");
    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
    ", 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("当前指向空闲内存大小不够,跳到下一块空闲内存
    ");
    797                 pFree = pFree->next;
    798             }
    799             else
    800             {
    801                 printf("没有足够大小的空闲内存可用,开始调度:
    ");
    802                 schedule();
    803                 printf("将所有空闲内存块紧缩并排序
    ");
    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 }
    内存管理
  • 相关阅读:
    MDK软件2020年到期和谐方法
    TinyMCE插件CodeSample前后端应用
    KEIL MDK编译后的代码量和RAM使用详解
    pdf密码解除工具
    Keil c中自定义带可变参数的printf函数
    关于"云服务器被检测到对外攻击已阻断该服务器对其它服务器端口的访问"的解决措施
    在 __CC_ARM 编译器环境下,使用$Sub$$ 与 $Super$$ 的“补丁”功能
    thinkphp前台html格式化输出日期
    ELINK编程器典型场景之序列号烧写
    数据在数组中存储的顺序:小端 OR 大端模式 详解
  • 原文地址:https://www.cnblogs.com/2020R/p/13478663.html
Copyright © 2011-2022 走看看