数据结构+操作系统实验代码
目录:
实验一:
邻接表:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int MAX = 30; 4 typedef int SubType; 5 typedef bool WeightType; 6 struct Node//结点 7 { 8 SubType sub; 9 WeightType weight; 10 struct Node* pNext = NULL; 11 }; 12 typedef struct Vertex//表顶点 13 { 14 struct Node* pHead; 15 }AdjList[MAX]; 16 void Insert_(AdjList adj, SubType v1, SubType v2, WeightType w) 17 { 18 struct Node* s = new struct Node; 19 s->pNext = NULL; 20 s->sub = v2; 21 s->weight = w; 22 if (adj[v1].pHead == NULL) 23 { 24 adj[v1].pHead = s; 25 } 26 else 27 { 28 struct Node* p = adj[v1].pHead; 29 struct Node* pr = NULL; 30 while (p != NULL) 31 { 32 if (p->sub == v2)//已存在,无需插入,修改权值 33 { 34 p->weight = w; 35 return; 36 } 37 pr = p; 38 p = p->pNext; 39 } 40 pr->pNext = s; 41 } 42 } 43 void Insert(AdjList adj, SubType v1, SubType v2, WeightType w) 44 { 45 Insert_(adj, v1, v2, w); 46 Insert_(adj, v2, v1, w); 47 } 48 int main() 49 { 50 AdjList G; 51 for (int i = 0; i < MAX; ++i) 52 G[i].pHead = NULL; 53 54 Insert(G, 0, 2, true); 55 56 return 0; 57 }
邻接矩阵:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int MAX = 30; 4 typedef int SubType; 5 typedef bool WeightType; 6 void Insert(WeightType (*G)[MAX], SubType v1, SubType v2, WeightType w) 7 { 8 G[v1][v2] = G[v2][v1] = w; 9 } 10 int main() 11 { 12 WeightType G[MAX][MAX]; 13 for(int i=0;i<MAX;++i) 14 for (int j = 0; j < MAX; ++j) 15 { 16 G[i][j] = i == j ? true : false; 17 } 18 Insert(G, 0, 5, true); 19 return 0; 20 }
实验二:
BFS+DFS(邻接表):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int MAX = 30; 4 int first = 0; 5 typedef int SubType; 6 typedef bool WeightType; 7 bool visited[MAX][MAX]; 8 bool inQueue[MAX]; 9 typedef struct Node//结点 10 { 11 SubType sub; 12 WeightType weight; 13 struct Node* pNext = NULL; 14 }; 15 struct Queue 16 { 17 SubType s[MAX]; 18 int r = -1; 19 int f = -1; 20 }; 21 Queue q; 22 typedef struct Vertex//表顶点 23 { 24 struct Node* pHead; 25 }AdjList[MAX]; 26 void Insert_(AdjList adj, SubType v1, SubType v2, WeightType w) 27 { 28 struct Node* s = new struct Node; 29 s->pNext = NULL; 30 s->sub = v2; 31 s->weight = w; 32 if (adj[v1].pHead == NULL) 33 { 34 adj[v1].pHead = s; 35 } 36 else 37 { 38 struct Node* p = adj[v1].pHead; 39 struct Node* pr = NULL; 40 while (p != NULL) 41 { 42 if (p->sub == v2)//已存在,无需插入,修改权值 43 { 44 p->weight = w; 45 return; 46 } 47 pr = p; 48 p = p->pNext; 49 } 50 pr->pNext = s; 51 } 52 } 53 void Insert(AdjList adj, SubType v1, SubType v2, WeightType w) 54 { 55 Insert_(adj, v1, v2, w); 56 Insert_(adj, v2, v1, w); 57 } 58 void dfs(AdjList G, SubType i) 59 { 60 struct Node* p = G[i].pHead; 61 while (p != NULL) 62 { 63 if (!visited[i][p->sub] && p->weight == true) 64 { 65 visited[i][p->sub] = visited[p->sub][i] = true; 66 if (first != 0) cout << "->"; 67 ++first; 68 cout << "(" << i << "," << p->sub << ")"; 69 dfs(G, p->sub); 70 } 71 p = p->pNext; 72 } 73 } 74 void bfs(AdjList G, SubType i) 75 { 76 q.s[++q.f] = i; 77 inQueue[i] = true; 78 int cnt = 0; 79 while (q.r < q.f) 80 { 81 SubType n = q.s[++q.r]; 82 if (cnt != 0)cout << "->"; 83 ++cnt; 84 cout << n; 85 struct Node* p = G[n].pHead; 86 while (p != NULL) 87 { 88 if (!inQueue[p->sub]) 89 { 90 inQueue[p->sub] = true; 91 q.s[++q.f] = p->sub; 92 } 93 p = p->pNext; 94 } 95 } 96 } 97 int main() 98 { 99 AdjList G; 100 for (int i = 0; i < MAX; ++i) 101 G[i].pHead = NULL; 102 for (int i = 0; i < MAX; ++i) 103 for (int j = 0; j < MAX; ++j) 104 { 105 visited[i][j] = visited[j][i] = false; 106 } 107 Insert(G, 0, 2, true); 108 Insert(G, 5, 2, true); 109 Insert(G, 6, 3, true); 110 Insert(G, 7, 2, true); 111 Insert(G, 9, 3, true); 112 Insert(G, 2, 3, true); 113 cout << "DFS:"; 114 dfs(G, 0); 115 cout << endl; 116 cout << "BFS:"; 117 bfs(G, 0); 118 return 0; 119 }
实验三:
最小生成树(邻接表):
Prim和Kruskal:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 typedef int NumType; 4 typedef int WeightType; 5 const WeightType INFINITE = 65535; 6 const NumType MAX = 6; 7 #define MAXEDGE MAX * MAX 8 bool InsertFlag = true; 9 int EdgeCnt = 0; 10 struct Node//结点 11 { 12 NumType sub; 13 WeightType weight; 14 struct Node* pNext = NULL; 15 }; 16 typedef struct Vertex//表顶点 17 { 18 struct Node* pHead; 19 }AdjList[MAX]; 20 struct Edge 21 { 22 NumType u, v; 23 WeightType w; 24 }; 25 struct Edge* edge = new struct Edge[MAXEDGE]; 26 int r = -1; 27 void Insert_(AdjList adj, NumType v1, NumType v2, WeightType w) 28 { 29 struct Node* s = new struct Node; 30 s->pNext = NULL; 31 s->sub = v2; 32 s->weight = w; 33 if (adj[v1].pHead == NULL) 34 { 35 adj[v1].pHead = s; 36 } 37 else 38 { 39 struct Node* p = adj[v1].pHead; 40 struct Node* pr = NULL; 41 while (p != NULL) 42 { 43 if (p->sub == v2)//已存在,无需插入,修改权值 44 { 45 InsertFlag = false; 46 p->weight = w; 47 return; 48 } 49 pr = p; 50 p = p->pNext; 51 } 52 pr->pNext = s; 53 } 54 } 55 void Insert(AdjList adj, NumType v1, NumType v2, WeightType w) 56 { 57 InsertFlag = true;//成功插入边 58 Insert_(adj, v1, v2, w); 59 Insert_(adj, v2, v1, w); 60 if (InsertFlag) 61 { 62 ++EdgeCnt; 63 edge[++r].u = v1; 64 edge[r].v = v2; 65 edge[r].w = w; 66 } 67 } 68 NumType min[];//存储在最小生成树内的点的编号 69 bool visited[MAX][MAX]; 70 WeightType prim(AdjList G)//返回最小边权和 71 { 72 WeightType ret = 0;//最小和 73 WeightType dis[MAX];//各点到最小生成树的距离 74 fill(dis, dis + MAX, INFINITE);//初始化为INFINITE 75 dis[0] = 0; 76 struct Node* p = G[0].pHead; 77 while (p != NULL) 78 { 79 dis[p->sub] = p->weight;//把与0相接的点距离0点的距离放入dis 80 p = p->pNext; 81 } 82 83 for (int i = 0; i < MAX-1; ++i)//循环MAX次 84 { 85 WeightType min = INFINITE; 86 int k = -1;//存储最小dis的下标 87 for (int j = 0; j < MAX; ++j)//找出最小dis 88 { 89 if (dis[j] != 0 && dis[j] < min) 90 { 91 min = dis[j]; 92 k = j; 93 } 94 } 95 if (k == -1) return -1;//不连通 96 ret += min;//更新边权和 97 dis[k] = 0;//k纳入最小生成树 98 WeightType temp[MAX];//存储k与相接点的权 99 fill(temp, temp + MAX, INFINITE); 100 p = G[k].pHead; 101 while (p != NULL) 102 { 103 temp[p->sub] = p->weight; 104 p = p->pNext; 105 } 106 for (int i = 0; i < MAX; ++i)//如果未访问点dis值由于k的纳入变得更小,则更新 107 { 108 if (dis[i] != 0 && temp[i] != INFINITE && temp[i] < dis[i]) 109 dis[i] = temp[i]; 110 } 111 } 112 return ret; 113 } 114 //-----------------------Kruskal------------------------ 115 NumType root[MAX]; 116 NumType FindRoot(NumType x) 117 { 118 NumType t = x; 119 while (root[x] != x) 120 { 121 x = root[x]; 122 } 123 return x; 124 } 125 WeightType kruskal(AdjList G) 126 { 127 WeightType ret = 0; 128 int EdgeNum = 0; 129 for (int i = 0; i < EdgeCnt; ++i)//排序 130 { 131 for (int j = 1; j < EdgeCnt; ++j) 132 { 133 if (edge[j].w < edge[j - 1].w) 134 { 135 struct Edge temp = edge[j]; 136 edge[j] = edge[j - 1]; 137 edge[j - 1] = temp; 138 } 139 } 140 } 141 142 for (int i = 0; i < EdgeCnt; ++i) 143 { 144 NumType ru = FindRoot(edge[i].u); 145 NumType rv = FindRoot(edge[i].v); 146 if (ru != rv) 147 { 148 root[ru] = rv;//合并集合 149 ret += edge[i].w; 150 ++EdgeNum; 151 if (EdgeNum == MAX - 1) break;//变数为结点数-1,说明生成树构造完成 152 } 153 } 154 if (EdgeNum != MAX - 1) return -1;//图不连通 155 return ret; 156 } 157 158 int main() 159 { 160 AdjList G; 161 for (int i = 0; i < MAX; ++i) 162 G[i].pHead = NULL; 163 for (int i = 0; i < MAX; ++i) 164 root[i] = i; 165 //构造图 166 Insert(G, 0, 1, 4); 167 Insert(G, 0, 4, 1); 168 Insert(G, 0, 5, 2); 169 Insert(G, 1, 5, 3); 170 Insert(G, 2, 1, 6); 171 Insert(G, 2, 3, 6); 172 Insert(G, 2, 5, 5); 173 Insert(G, 3, 5, 5); 174 Insert(G, 3, 4, 4); 175 Insert(G, 4, 5, 3); 176 177 cout << "Prim:" << prim(G) <<endl; 178 179 cout << "Kruskal:" << kruskal(G) << endl; 180 181 return 0; 182 }
实验四:
最短路径
Dijkstra:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int INFINITE = 65535; 4 const int N = 10; 5 int pre[N]; 6 int r = -1; 7 int G[N][N]; 8 void Dijkstra(int(*G)[N], int start, int dis[]) 9 { 10 bool visited[N]; 11 for (int i = 0; i < N; ++i) dis[i] = G[start][i]; 12 dis[start] = 0; 13 for (int i = 0; i < N; ++i) visited[i] = false; 14 visited[start] = true; 15 for (int i = 0; i < N; ++i) 16 { 17 dis[i] = G[start][i]; 18 pre[i] = start; 19 } 20 dis[start] = 0; 21 for (int i = 0; i < N; ++i) 22 { 23 int min = INFINITE; 24 int k = 0; 25 for (int j = 0; j < N; ++j) 26 { 27 if (dis[j] < min && visited[j] == false) 28 { 29 min = dis[j]; 30 k = j; 31 } 32 } 33 visited[k] = true; 34 for (int v = 0; v < N; ++v) 35 { 36 if (dis[k] + G[k][v] < dis[v] && visited[v] == false) 37 { 38 dis[v] = dis[k] + G[k][v]; 39 pre[v] = k; 40 } 41 42 } 43 } 44 } 45 void set(int i, int j, int w) 46 { 47 G[i][j] = G[j][i] = w; 48 } 49 int main() 50 { 51 for (int i = 0; i < N; ++i) 52 for (int j = 0; j < N; ++j) 53 G[i][j] = INFINITE; 54 set(0, 1, 50); 55 set(0, 5, 1); 56 set(0, 8, 18); 57 set(1, 5, 7); 58 set(1, 2, 5); 59 set(2, 5, 2); 60 set(2, 3, 7); 61 set(2, 6, 10); 62 set(3, 4, 8); 63 set(3, 7, 1); 64 set(3, 6, 10); 65 set(4, 7, 1); 66 set(5, 6, 1); 67 set(5, 8, 15); 68 set(6, 8, 5); 69 set(6, 7, 1); 70 set(6, 9, 3); 71 set(8, 9, 1); 72 set(7, 9, 1); 73 int dis[N];//start到其余点的距离 74 int start = 0; 75 Dijkstra(G, start, dis); 76 77 for (int i = 0; i < N; ++i) 78 { 79 if (i == start)continue; 80 cout << start << "到" << i << "的最短路径长度:" << dis[i] << " "; 81 cout << "路径:"; 82 int out[N]; 83 int rOut = -1; 84 int e = i; 85 while (e != start) 86 { 87 out[++rOut] = e; 88 e = pre[e]; 89 } 90 out[++rOut] = start; 91 bool outFirst = true; 92 while (rOut != -1) 93 { 94 if (!outFirst) 95 cout << "->"; 96 cout << out[rOut--]; 97 outFirst = false; 98 } 99 cout << endl; 100 } 101 return 0; 102
实验五
最短路径
Floyd:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int INFINITE = 65535; 4 const int N = 10; 5 int G[N][N]; 6 int pre[N]; 7 int r = -1; 8 int dis[N][N]; 9 int path[N][N];//保存路径 10 void Floyd(int(*G)[N]) 11 { 12 for (int i = 0; i < N; ++i) 13 for (int j = 0; j < N; ++j) 14 { 15 dis[i][j] = G[i][j]; 16 path[i][j] = j; 17 } 18 19 for (int i = 0; i < N; ++i) 20 dis[i][i] = 0; 21 for(int k=0; k<N; ++k) 22 for(int i=0; i<N; ++i) 23 for (int j = 0; j < N; ++j) 24 { 25 if (dis[i][k] != INFINITE && dis[k][j] != INFINITE && dis[i][k] + dis[k][j] < dis[i][j]) 26 { 27 dis[i][j] = dis[i][k] + dis[k][j]; 28 path[i][j] = path[i][k]; 29 } 30 } 31 } 32 void print(int s, int e) 33 { 34 int t = path[s][e]; 35 cout << "->" << t; 36 if (t == e) return; 37 print(t, e); 38 } 39 void Print(int s, int e) 40 { 41 cout << s; 42 print(s, e); 43 } 44 void set(int i, int j,int w) 45 { 46 G[i][j] = G[j][i] = w; 47 } 48 int main() 49 { 50 for (int i = 0; i < N; ++i) 51 for (int j = 0; j < N; ++j) 52 G[i][j] = INFINITE; 53 set(0, 1, 50); 54 set(0, 5, 1); 55 set(0, 8, 18); 56 set(1, 5, 7); 57 set(1, 2, 5); 58 set(2, 5, 2); 59 set(2, 3, 7); 60 set(2, 6, 10); 61 set(3, 4, 8); 62 set(3, 7, 1); 63 set(3, 6, 10); 64 set(4, 7, 1); 65 set(5, 6, 1); 66 set(5, 8, 15); 67 set(6, 8, 5); 68 set(6, 7, 1); 69 set(6, 9, 3); 70 set(8, 9, 1); 71 set(7, 9, 1); 72 Floyd(G); 73 74 for (int i = 0; i < N; ++i) 75 { 76 for (int j = 0; j < N; ++j) 77 { 78 cout << i << "到" << j << "最短路径长度:" << dis[i][j] << endl; 79 cout << "路径为:"; 80 Print(i, j); 81 cout << endl; 82 } 83 cout << endl; 84 } 85 return 0; 86 }
实验六:图的综合应用
1 #include <iostream> 2 using namespace std; 3 const int INFINITE = 65535; 4 const int MAX = 20; 5 typedef int WeightType; 6 typedef int NumType;//结点编号类型 7 const int N = 17; 8 int E = 0;//边数 9 WeightType G[MAX][MAX]; 10 struct Edge 11 { 12 NumType u, v; 13 WeightType w; 14 }; 15 struct Edge* edge = new struct Edge[N*N]; 16 int rEdge = -1; 17 void set(int i, int j, WeightType w) 18 { 19 if (G[i][j] == INFINITE) 20 { 21 ++E; 22 edge[++rEdge].u = i; 23 edge[rEdge].v = j; 24 edge[rEdge].w = w; 25 } 26 G[i][j] = G[j][i] = w; 27 } 28 struct Queue 29 { 30 int s[MAX]; 31 int r = -1, f = -1; 32 }; 33 Queue q; 34 bool inQueue[MAX]; 35 bool VISITED[MAX]; 36 37 void DFS(int i) 38 { 39 VISITED[i] = true; 40 for (int j = 0; j < N; ++j) 41 { 42 if (VISITED[j] == false && G[i][j] != INFINITE ) 43 { 44 cout << "(" << i << "->" << j << ")"; 45 DFS(j); 46 } 47 } 48 } 49 void BFS(int i) 50 { 51 q.s[++q.f] = i; 52 inQueue[i] = true; 53 int cnt = 0; 54 while (q.r < q.f) 55 { 56 int n= q.s[++q.r]; 57 if (cnt != 0)cout << "->"; 58 ++cnt; 59 cout << n; 60 for (int j = 0; j < N; ++j) 61 { 62 if (inQueue[j] == false && G[n][j] != INFINITE) 63 { 64 q.s[++q.f] = j; 65 inQueue[j] = true; 66 } 67 } 68 } 69 } 70 //Prim 71 int dis[N]; 72 WeightType Prim()//返回最小边权和 73 { 74 WeightType ret = 0;//最小和 75 WeightType dis[MAX];//各点到最小生成树的距离 76 fill(dis, dis + MAX, INFINITE);//初始化为INFINITE 77 dis[0] = 0;//从0开始 78 for (int i = 1; i < N; ++i)//把与0相接的点距离0点的距离放入dis 79 { 80 if (G[0][i] != INFINITE) 81 dis[i] = G[0][i]; 82 } 83 84 for (int i = 0; i < N - 1; ++i)//循环MAX次 85 { 86 WeightType min = INFINITE; 87 int k = -1;//存储最小dis的下标 88 for (int j = 0; j < MAX; ++j)//找出最小dis 89 { 90 if (dis[j] != 0 && dis[j] < min) 91 { 92 min = dis[j]; 93 k = j; 94 } 95 } 96 if (k == -1) return -1;//不连通 97 ret += min;//更新边权和 98 dis[k] = 0;//k纳入最小生成树 99 WeightType temp[MAX];//存储k与相接点的权 100 fill(temp, temp + MAX, INFINITE); 101 for (int i = 0; i < N; ++i) 102 { 103 if (temp[i] = G[k][i]); 104 } 105 for (int i = 0; i < MAX; ++i)//如果未访问点dis值由于k的纳入变得更小,则更新 106 { 107 if (dis[i] != 0 && temp[i] != INFINITE && temp[i] < dis[i]) 108 dis[i] = temp[i]; 109 } 110 } 111 return ret; 112 } 113 //Kruskal 114 NumType root[MAX]; 115 NumType FindRoot(NumType x) 116 { 117 NumType t = x; 118 while (root[x] != x) 119 { 120 x = root[x]; 121 } 122 return x; 123 } 124 WeightType Kruskal() 125 { 126 WeightType ret = 0; 127 int EdgeNum = 0; 128 for (int i = 0; i < E; ++i)//排序 129 { 130 for (int j = 1; j < E; ++j) 131 { 132 if (edge[j].w < edge[j - 1].w) 133 { 134 struct Edge temp = edge[j]; 135 edge[j] = edge[j - 1]; 136 edge[j - 1] = temp; 137 } 138 } 139 } 140 for (int i = 0; i < E; ++i) 141 { 142 NumType ru = FindRoot(edge[i].u); 143 NumType rv = FindRoot(edge[i].v); 144 if (ru != rv) 145 { 146 root[ru] = rv;//合并集合 147 ret += edge[i].w; 148 ++EdgeNum; 149 if (EdgeNum == N - 1) break;//边数为结点数-1,说明生成树构造完成 150 } 151 } 152 if (EdgeNum != N - 1) return -1;//图不连通 153 return ret; 154 } 155 //Dijkstra 156 void Dijkstra(int s) 157 { 158 int pre[N]; 159 int dis[N]; 160 bool visited[N]; 161 for (int i = 0; i < N; ++i) visited[i] = false; 162 visited[s] = true; 163 for (int i = 0; i < N; ++i) 164 { 165 dis[i] = G[s][i]; 166 pre[i] = s; 167 } 168 dis[s] = 0; 169 for (int i = 0; i < N; ++i) 170 { 171 int min = INFINITE; 172 int k = 0; 173 for (int j = 0; j < N; ++j) 174 { 175 if (dis[j] < min && visited[j] == false) 176 { 177 visited[j] = true; 178 min = dis[j]; 179 k = j; 180 } 181 } 182 for (int v = 0; v < N; ++v) 183 { 184 if (dis[k] + G[k][v] < dis[v]) 185 { 186 dis[v] = dis[k] + G[k][v]; 187 pre[v] = k; 188 } 189 } 190 } 191 for (int i = 0; i < N; ++i) 192 { 193 if (i == s)continue; 194 cout << s << "到" << i << "的最短路径长度:" << dis[i] << " "; 195 cout << "路径:"; 196 int out[N]; 197 int rOut = -1; 198 int e = i; 199 while (e != s) 200 { 201 out[++rOut] = e; 202 e = pre[e]; 203 } 204 out[++rOut] = s; 205 bool outFirst = true; 206 while (rOut != -1) 207 { 208 if (!outFirst) 209 cout << "->"; 210 cout << out[rOut--]; 211 outFirst = false; 212 } 213 cout << endl; 214 } 215 } 216 //Floyd 217 int Dis[N][N]; 218 int path[N][N];//保存路径 219 void Floyd() 220 { 221 for (int i = 0; i < N; ++i) 222 for (int j = 0; j < N; ++j) 223 { 224 Dis[i][j] = G[i][j]; 225 path[i][j] = j; 226 } 227 228 for (int i = 0; i < N; ++i) 229 Dis[i][i] = 0; 230 for (int k = 0; k < N; ++k) 231 for (int i = 0; i < N; ++i) 232 for (int j = 0; j < N; ++j) 233 { 234 if (Dis[i][k] != INFINITE && Dis[k][j] != INFINITE && Dis[i][k] + Dis[k][j] < Dis[i][j]) 235 { 236 Dis[i][j] = Dis[i][k] + Dis[k][j]; 237 path[i][j] = path[i][k]; 238 } 239 } 240 } 241 void print(int s, int e) 242 { 243 int t = path[s][e]; 244 cout << "->" << t; 245 if (t == e) return; 246 print(t, e); 247 } 248 void Print(int s, int e) 249 { 250 cout << s; 251 print(s, e); 252 } 253 254 int main() 255 { 256 for (int i = 0; i < MAX; ++i) 257 for (int j = 0; j < MAX; ++j) 258 G[i][j] = (i==j ? 0 : INFINITE); 259 int order; 260 for (int i = 0; i < MAX; ++i) 261 VISITED[i] = false; 262 for (int i = 0; i < MAX; ++i) 263 inQueue[i] = false; 264 for (int i = 0; i < N; ++i) 265 root[i] = i; 266 //构造图 267 set(0, 1, 1); set(0, 14, 1); set(1, 2, 10); set(2, 14, 1); set(14, 13, 1); set(13, 12, 10); 268 set(2, 3, 10); set(12, 16, 1); set(3, 4, 1); set(11, 4, 1); set(16, 10, 1); set(15, 10, 1); 269 set(10, 9, 20); set(11, 9, 1); set(15, 7, 1); set(5, 7, 1); set(5, 6, 10); set(6, 9, 1); 270 set(4, 8, 1); set(2, 7, 1); set(4, 5, 1); 271 cout << "选择功能" << endl 272 << "1.使用DFS遍历输出图" << endl 273 << "2.使用BFS遍历输出图" << endl 274 << "3.求最小生成树(Prim算法)" << endl 275 << "4.求最小生成树(Kruskal算法)" << endl 276 << "5.求点s到其余点的最短路径(Dijkstra算法)" << endl 277 << "6.求各点间的最短路径(Floyd算法)" << endl; 278 279 while (cin >> order) 280 { 281 if (order == 1)//dfs 282 { 283 cout << "输入起点:"; 284 int s; 285 cin >> s; 286 DFS(s); 287 } 288 if (order == 2)//bfs 289 { 290 cout << "输入起点:"; 291 int s; 292 cin >> s; 293 BFS(s); 294 } 295 if (order == 3) 296 { 297 cout << "最小生成树边权和(Prim):"<<Prim(); 298 } 299 if (order == 4) 300 { 301 cout << "最小生成树边权和(Kruskal):" << Kruskal(); 302 } 303 if (order == 5) 304 { 305 cout << "输入点s编号:"; 306 int s; 307 cin >> s; 308 Dijkstra(s); 309 } 310 if (order == 6) 311 { 312 Floyd(); 313 for (int i = 0; i < N; ++i) 314 { 315 for (int j = 0; j < N; ++j) 316 { 317 cout << i << "到" << j << "最短路径长度:" << Dis[i][j] << endl; 318 cout << "路径为:"; 319 Print(i, j); 320 cout << endl; 321 } 322 cout << endl; 323 } 324 } 325 cout << endl << "已完成,请输入:"; 326 } 327 328 329 return 0; 330
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int INFINITE = 65535; 4 const int MAX = 20; 5 typedef int WeightType; 6 typedef int NumType;//结点编号类型 7 const int N = 17; 8 int E = 0;//边数 9 WeightType G[MAX][MAX]; 10 struct Edge 11 { 12 NumType u, v; 13 WeightType w; 14 }; 15 struct Edge* edge = new struct Edge[N * N]; 16 int rEdge = -1; 17 void set(int i, int j, WeightType w) 18 { 19 if (G[i][j] == INFINITE) 20 { 21 ++E; 22 edge[++rEdge].u = i; 23 edge[rEdge].v = j; 24 edge[rEdge].w = w; 25 } 26 G[i][j] = G[j][i] = w; 27 } 28 struct Queue 29 { 30 int s[MAX]; 31 int r = -1, f = -1; 32 }; 33 Queue q; 34 bool inQueue[MAX]; 35 bool VISITED[MAX]; 36 37 void DFS(int i) 38 { 39 VISITED[i] = true; 40 for (int j = 0; j < N; ++j) 41 { 42 if (VISITED[j] == false && G[i][j] != INFINITE) 43 { 44 cout << "(" << i << "->" << j << ")"; 45 DFS(j); 46 } 47 } 48 } 49 void BFS(int i) 50 { 51 q.s[++q.f] = i; 52 inQueue[i] = true; 53 int cnt = 0; 54 while (q.r < q.f) 55 { 56 int n = q.s[++q.r]; 57 if (cnt != 0)cout << "->"; 58 ++cnt; 59 cout << n; 60 for (int j = 0; j < N; ++j) 61 { 62 if (inQueue[j] == false && G[n][j] != INFINITE) 63 { 64 q.s[++q.f] = j; 65 inQueue[j] = true; 66 } 67 } 68 } 69 } 70 //Prim 71 int dis[N]; 72 WeightType Prim()//返回最小边权和 73 { 74 WeightType ret = 0;//最小和 75 WeightType dis[MAX];//各点到最小生成树的距离 76 fill(dis, dis + MAX, INFINITE);//初始化为INFINITE 77 dis[0] = 0;//从0开始 78 for (int i = 1; i < N; ++i)//把与0相接的点距离0点的距离放入dis 79 { 80 if (G[0][i] != INFINITE) 81 dis[i] = G[0][i]; 82 } 83 84 for (int i = 0; i < N - 1; ++i)//循环MAX次 85 { 86 WeightType min = INFINITE; 87 int k = -1;//存储最小dis的下标 88 for (int j = 0; j < MAX; ++j)//找出最小dis 89 { 90 if (dis[j] != 0 && dis[j] < min) 91 { 92 min = dis[j]; 93 k = j; 94 } 95 } 96 if (k == -1) return -1;//不连通 97 ret += min;//更新边权和 98 dis[k] = 0;//k纳入最小生成树 99 WeightType temp[MAX];//存储k与相接点的权 100 fill(temp, temp + MAX, INFINITE); 101 for (int i = 0; i < N; ++i) 102 { 103 if (temp[i] = G[k][i]); 104 } 105 for (int i = 0; i < MAX; ++i)//如果未访问点dis值由于k的纳入变得更小,则更新 106 { 107 if (dis[i] != 0 && temp[i] != INFINITE && temp[i] < dis[i]) 108 dis[i] = temp[i]; 109 } 110 } 111 return ret; 112 } 113 //Kruskal 114 NumType root[MAX]; 115 NumType FindRoot(NumType x) 116 { 117 NumType t = x; 118 while (root[x] != x) 119 { 120 x = root[x]; 121 } 122 return x; 123 } 124 WeightType Kruskal() 125 { 126 WeightType ret = 0; 127 int EdgeNum = 0; 128 for (int i = 0; i < E; ++i)//排序 129 { 130 for (int j = 1; j < E; ++j) 131 { 132 if (edge[j].w < edge[j - 1].w) 133 { 134 struct Edge temp = edge[j]; 135 edge[j] = edge[j - 1]; 136 edge[j - 1] = temp; 137 } 138 } 139 } 140 for (int i = 0; i < E; ++i) 141 { 142 NumType ru = FindRoot(edge[i].u); 143 NumType rv = FindRoot(edge[i].v); 144 if (ru != rv) 145 { 146 root[ru] = rv;//合并集合 147 ret += edge[i].w; 148 ++EdgeNum; 149 if (EdgeNum == N - 1) break;//边数为结点数-1,说明生成树构造完成 150 } 151 } 152 if (EdgeNum != N - 1) return -1;//图不连通 153 return ret; 154 } 155 //Dijkstra 156 void Dijkstra(int s) 157 { 158 int pre[N]; 159 int dis[N]; 160 bool visited[N]; 161 for (int i = 0; i < N; ++i) visited[i] = false; 162 visited[s] = true; 163 for (int i = 0; i < N; ++i) 164 { 165 dis[i] = G[s][i]; 166 pre[i] = s; 167 } 168 dis[s] = 0; 169 while (1) 170 { 171 int min = INFINITE; 172 int k = 0; 173 for (int j = 0; j < N; ++j) 174 { 175 if (dis[j] < min && visited[j] == false) 176 { 177 min = dis[j]; 178 k = j; 179 } 180 } 181 visited[k] = true; 182 if (min == INFINITE)break; 183 for (int v = 0; v < N; ++v) 184 { 185 if (dis[k] + G[k][v] < dis[v] && visited[v] == false ) 186 { 187 dis[v] = dis[k] + G[k][v]; 188 pre[v] = k; 189 } 190 } 191 } 192 for (int i = 0; i < N; ++i) 193 { 194 if (i == s)continue; 195 cout << s << "到" << i << "的最短路径长度:" << dis[i] << " "; 196 cout << "路径:"; 197 int out[N]; 198 int rOut = -1; 199 int e = i; 200 while (e != s) 201 { 202 out[++rOut] = e; 203 e = pre[e]; 204 } 205 out[++rOut] = s; 206 bool outFirst = true; 207 while (rOut != -1) 208 { 209 if (!outFirst) 210 cout << "->"; 211 cout << out[rOut--]; 212 outFirst = false; 213 } 214 cout << endl; 215 } 216 } 217 //Floyd 218 int Dis[N][N]; 219 int path[N][N];//保存路径 220 void Floyd() 221 { 222 for (int i = 0; i < N; ++i) 223 for (int j = 0; j < N; ++j) 224 { 225 Dis[i][j] = G[i][j]; 226 path[i][j] = j; 227 } 228 229 for (int i = 0; i < N; ++i) 230 Dis[i][i] = 0; 231 for (int k = 0; k < N; ++k) 232 for (int i = 0; i < N; ++i) 233 for (int j = 0; j < N; ++j) 234 { 235 if (Dis[i][k] != INFINITE && Dis[k][j] != INFINITE && Dis[i][k] + Dis[k][j] < Dis[i][j]) 236 { 237 Dis[i][j] = Dis[i][k] + Dis[k][j]; 238 path[i][j] = path[i][k]; 239 } 240 } 241 } 242 void print(int s, int e) 243 { 244 int t = path[s][e]; 245 cout << "->" << t; 246 if (t == e) return; 247 print(t, e); 248 } 249 void Print(int s, int e) 250 { 251 cout << s; 252 print(s, e); 253 } 254 255 int main() 256 { 257 for (int i = 0; i < MAX; ++i) 258 for (int j = 0; j < MAX; ++j) 259 G[i][j] = (i == j ? 0 : INFINITE); 260 int order; 261 //构造图 262 set(0, 1, 1); set(0, 14, 1); set(1, 2, 10); set(2, 14, 1); set(14, 13, 1); set(13, 12, 10); 263 set(2, 3, 10); set(12, 16, 1); set(3, 4, 1); set(11, 4, 1); set(16, 10, 1); set(15, 10, 1); 264 set(10, 9, 20); set(11, 9, 1); set(15, 7, 1); set(5, 7, 1); set(5, 6, 10); set(6, 9, 1); 265 set(4, 8, 1); set(2, 7, 1); set(4, 5, 1); 266 cout << "选择功能" << endl 267 << "1.使用DFS遍历输出图" << endl 268 << "2.使用BFS遍历输出图" << endl 269 << "3.求最小生成树(Prim算法)" << endl 270 << "4.求最小生成树(Kruskal算法)" << endl 271 << "5.求点s到其余点的最短路径(Dijkstra算法)" << endl 272 << "6.求各点间的最短路径(Floyd算法)" << endl; 273 274 while (cin >> order) 275 { 276 if (order == 1)//dfs 277 { 278 for (int i = 0; i < MAX; ++i) 279 VISITED[i] = false; 280 cout << "输入起点:"; 281 int s; 282 cin >> s; 283 DFS(s); 284 } 285 if (order == 2)//bfs 286 { 287 for (int i = 0; i < MAX; ++i) 288 inQueue[i] = false; 289 q.f = q.r = -1; 290 cout << "输入起点:"; 291 int s; 292 cin >> s; 293 BFS(s); 294 } 295 if (order == 3) 296 { 297 cout << "最小生成树边权和(Prim):" << Prim(); 298 } 299 if (order == 4) 300 { 301 for (int i = 0; i < N; ++i) 302 root[i] = i; 303 cout << "最小生成树边权和(Kruskal):" << Kruskal(); 304 } 305 if (order == 5) 306 { 307 cout << "输入点s编号:"; 308 int s; 309 cin >> s; 310 Dijkstra(s); 311 } 312 if (order == 6) 313 { 314 Floyd(); 315 for (int i = 0; i < N; ++i) 316 { 317 for (int j = 0; j < N; ++j) 318 { 319 cout << i << "到" << j << "最短路径长度:" << Dis[i][j] << endl; 320 cout << "路径为:"; 321 Print(i, j); 322 cout << endl; 323 } 324 cout << endl; 325 } 326 } 327 cout << endl << "已完成,请输入:"; 328 } 329 330 331 return 0; 332 }
实验八:
多线程
哲学家就餐
问题:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <pthread.h> 3 #include <semaphore.h> 4 #define N 5//number of philosofer 5 #define LEFT i 6 #define RIGHT (i+1)%N 7 sem_t chopstick[N]; 8 sem_t four; 9 sem_t one; 10 pthread_t thread[N]; 11 int philosopher[N];//their number 12 int func_num = 0; 13 void thinking(int i) 14 { 15 printf("philosopher %d is thingking(func%d)\n", i + 1, func_num); 16 sleep(1); 17 } 18 void eating(int i) 19 { 20 printf("philosopher %d is eating(func%d)\n", i + 1, func_num); 21 sleep(1); 22 } 23 void* func1(void* param)//初始方法 24 { 25 int i = *((int*)param); 26 while (1) 27 { 28 thinking(i); 29 sem_wait(&chopstick[LEFT]); 30 sem_wait(&chopstick[RIGHT]); 31 eating(i); 32 sem_post(&chopstick[LEFT]); 33 sem_post(&chopstick[RIGHT]); 34 thinking(1); 35 } 36 pthread_exit(NULL); 37 } 38 void* func2(void* param)//不对称的方法 39 { 40 int i = *((int*)param); 41 while (1) 42 { 43 thinking(i); 44 if (i % 2 == 0) 45 { 46 sem_wait(&chopstick[LEFT]); 47 sem_wait(&chopstick[RIGHT]); 48 eating(i); 49 sem_post(&chopstick[RIGHT]); 50 sem_post(&chopstick[LEFT]); 51 } 52 else 53 { 54 sem_wait(&chopstick[RIGHT]); 55 sem_wait(&chopstick[LEFT]); 56 eating(i); 57 sem_post(&chopstick[LEFT]); 58 sem_post(&chopstick[RIGHT]); 59 } 60 thinking(i); 61 } 62 pthread_exit(NULL); 63 } 64 void* func3(void* param)//最多4个哲学家同时就餐 65 { 66 int i = *((int*)param); 67 while (1) 68 { 69 thinking(i); 70 sem_wait(&four); 71 sem_wait(&chopstick[LEFT]); 72 sem_wait(&chopstick[RIGHT]); 73 eating(i); 74 sem_post(&chopstick[RIGHT]); 75 sem_post(&chopstick[LEFT]); 76 sem_post(&four); 77 thinking(i); 78 } 79 pthread_exit(NULL); 80 } 81 void* func4(void* param)//只有当左右筷子都可用时才拿起筷子 82 { 83 int i = *((int*)param); 84 while (1) 85 { 86 thinking(i); 87 sem_wait(&one); 88 sem_wait(&chopstick[LEFT]); 89 sem_wait(&chopstick[RIGHT]); 90 sem_post(&one); 91 eating(i); 92 sem_post(&chopstick[RIGHT]); 93 sem_post(&chopstick[LEFT]); 94 thinking(i); 95 } 96 pthread_exit(NULL); 97 } 98 void thread_create() 99 { 100 int t; 101 for (int i = 0; i < N; ++i) 102 { 103 //t=pthread_create(&thread[i],NULL,func1,&philosopher[i]); func_num = 1; 104 //t=pthread_create(&thread[i],NULL,func2,&philosopher[i]); func_num = 2; 105 //t=pthread_create(&thread[i],NULL,func3,&philosopher[i]); func_num = 3; 106 t = pthread_create(&thread[i], NULL, func4, &philosopher[i]); func_num = 4; 107 if (t != 0) 108 printf("failed in creating thread%d\n", i); 109 } 110 } 111 thread_wait() 112 { 113 for (int i = 0; i < N; ++i) 114 { 115 pthread_join(thread[i], NULL); 116 printf("thread %d is ended", i); 117 } 118 } 119 int main() 120 { 121 for (int i = 0; i < N; ++i) 122 { 123 sem_init(&chopstick[i], 0, 1); 124 philosopher[i] = i; 125 } 126 sem_init(&four, 0, 4); 127 sem_init(&one, 0, 4); 128 thread_create(); 129 thread_wait(); 130 return 0; 131 }
多线程共享资源:多个线程共享变量sum
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <pthread.h> 3 #include<time.h> 4 #include <semaphore.h> 5 #define N 10 6 pthread_t thread[100]; 7 unsigned long int sum=0; 8 9 void count(void *param) 10 { 11 int i = *((int*)param); 12 while(1) 13 { 14 if(sum == 1024)break; 15 sum += 1; 16 printf("thread%d: sum = %d\n", i,sum); 17 } 18 } 19 void thread_create() 20 { 21 int t; 22 for(int i=0; i<N; ++i) 23 { 24 t=pthread_create(&thread[i],NULL,count, &i); 25 if(t != 0) 26 { 27 printf("failed in creating thread%d\n",i); 28 } 29 } 30 } 31 thread_wait() 32 { 33 for(int i=0; i<N; ++i) 34 { 35 pthread_join(thread[i],NULL); 36 printf("thread %d is ended\n", i); 37 } 38 } 39 int main() 40 { 41 thread_create(); 42 thread_wait(); 43 return 0; 44 }
实验九:
1、设计并实现操作系统读者写者问题读者优先算法。
只要有一个读者在读,其他读者就无需等待
为什么?因为如果有读者了,说明在读写者的竞争中,读者得到了资源,后面来的读者就可以直接读了
2、设计并实现操作系统读者写者问题写者优先算法。
放一起:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <pthread.h> 3 #include <semaphore.h> 4 #define N_reader 3 5 #define N_writer 3 6 pthread_t reader_thread[3], writer_thread[3]; 7 struct student 8 { 9 char name[10]; 10 int id; 11 }; 12 struct student idr[N_reader], idw[N_writer]; 13 int read_count = 0; 14 int write_count = 0; 15 sem_t mutex; 16 sem_t rcnt_mutex; 17 sem_t wcnt_mutex; 18 sem_t rw_mutex;//读者-写者、写者-写者之间的互斥, 19 sem_t r_mutex; 20 sem_t w_mutex; 21 sem_t out_mutex; 22 void reading(int i) 23 { 24 printf("reader%d is reading2\n",i); 25 26 } 27 void writing(int i) 28 { 29 printf("writer%d is writng2\n",i); 30 } 31 //--------------读者优先----------------- 32 void* read1(void *param) 33 { 34 int i = *((int*)param); 35 while(1) 36 { 37 sem_wait(&mutex); 38 ++read_count; 39 if(read_count == 1) 40 sem_wait(&rw_mutex); 41 sem_post(&mutex); 42 reading(i); 43 sem_wait(&mutex); 44 --read_count; 45 if(read_count == 0) 46 sem_post(&rw_mutex); 47 sem_post(&mutex); 48 sleep(1); 49 } 50 pthread_exit(NULL); 51 } 52 void* write1(void *param) 53 { 54 int i = *((int*)param); 55 while(1) 56 { 57 sem_wait(&rw_mutex); 58 writing(i); 59 sem_post(&rw_mutex); 60 sleep(1); 61 } 62 pthread_exit(NULL); 63 } 64 //--------------写者优先----------------- 65 void read2(void *param) 66 { 67 int i = *((int*)param); 68 while(1) 69 { 70 sem_wait(&out_mutex); 71 sem_wait(&r_mutex);//只有在写完成后才能获得r_mutex 72 73 sem_wait(&rcnt_mutex); 74 ++read_count; 75 if(read_count == 1) 76 sem_wait(&w_mutex);//如果是第一个读者,上w_mutex,防止读的时候写入,可以多个读者同时读 77 sem_post(&rcnt_mutex); 78 sem_post(&r_mutex); 79 sem_post(&out_mutex); 80 81 reading(i); 82 83 sem_wait(&rcnt_mutex); 84 --read_count; 85 if(read_count == 0) 86 sem_post(&w_mutex);//读完之后,释放w_mutex 87 sem_post(&rcnt_mutex); 88 89 90 sleep(1); 91 } 92 pthread_exit(NULL); 93 } 94 void write2(void *param) 95 { 96 int i = *((int*)param); 97 while(1) 98 { 99 sem_wait(&wcnt_mutex); 100 ++write_count; 101 if(write_count == 1) 102 sem_wait(&r_mutex);//上r_mutex,防止读者进入队列 103 sem_post(&wcnt_mutex); 104 105 sem_wait(&w_mutex);//与其他写操作互斥 106 writing(i); 107 sem_post(&w_mutex); 108 109 sem_wait(&wcnt_mutex); 110 --write_count; 111 if(write_count == 0) 112 sem_post(&r_mutex);//只有当所有写者完成操作,才释放r_mutex 113 sem_post(&wcnt_mutex); 114 115 sleep(1); 116 } 117 pthread_exit(NULL); 118 } 119 void thread_create() 120 { 121 int t; 122 for(int i=0; i<N_writer; ++i) 123 { 124 t=pthread_create(&writer_thread[i],NULL,write2,&idw[i].id); 125 if(t != 0) 126 { 127 printf("failed in creating thread%d\n",i); 128 } 129 } 130 for(int i=0; i<N_reader; ++i) 131 { 132 t=pthread_create(&reader_thread[i],NULL,read2,&idr[i].id); 133 if(t != 0) 134 { 135 printf("failed in creating thread%d\n",i); 136 } 137 } 138 } 139 thread_wait() 140 { 141 for(int i=0; i<N_reader; ++i) 142 { 143 pthread_join(reader_thread[i],NULL); 144 printf("reader_thread %d is ended\n", i); 145 } 146 for(int i=0; i<N_writer; ++i) 147 { 148 pthread_join(writer_thread[i],NULL); 149 printf("writer_thread %d is ended\n", i); 150 } 151 } 152 int main() 153 { 154 sem_init(&mutex,0,1); 155 sem_init(&rw_mutex,0,1); 156 sem_init(&r_mutex,0,1); 157 sem_init(&w_mutex,0,1); 158 sem_init(&rcnt_mutex,0,1); 159 sem_init(&wcnt_mutex,0,1); 160 sem_init(&out_mutex,0,1); 161 for(int i=0; i<N_reader+N_writer; ++i) 162 { 163 idr[i].id = i+1; 164 idw[i].id = i+1; 165 } 166 thread_create(); 167 thread_wait(); 168 return 0; 169 }
末尾有“2”的为写者优先的程序运行结果
实验十:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <semaphore.h> 4 #include <unistd.h> 5 #include <time.h> 6 #include <sys/types.h> 7 #include <pthread.h> 8 #define bool int 9 #define true 1 10 #define false 0 11 #define THREAD_MAXN 5//线程数 12 #define RUNTIME_SUB 1//每次运行线程减去的运行时间 13 //-----结构体定义 14 typedef struct TCB//存储线程信息 15 { 16 int thread_id;//线程编号 17 int arriveTime;//线程到达时间 18 int runTime;//持续时间 19 int finishTime;//完成时间 20 int wholeTime;//周转时间 21 double weightWholeTime;//带权周转时间 22 bool Finished;//线程是否完成 23 struct TCB* next;//使用链式存储方式 24 }TCB; 25 struct tcb_queue//TCB队列定义 26 { 27 struct TCB* tcbQueue[THREAD_MAXN];//TCB指针数组 28 int r,f; 29 }; 30 struct thread_pool//线程池结构体 31 { 32 pthread_mutex_t tcb_lock;//互斥锁 33 int fDestroyed;//线程池是否被销毁 34 pthread_t *threadid;//存储线程标识符指针 35 struct TCB *nowRunThread;//指向当前正在运行的线程 36 int nExist;//现存现存 37 int nFinish;//当前已完成的线程数 38 sem_t sem[THREAD_MAXN];//用于控制线程的信号量 39 struct tcb_queue rrQueue;//轮转队列 40 struct tcb_queue showQueue;//用于辅助打印的队列 41 struct TCB *tcb;//存储TCB 42 }; 43 //-----全局变量定义 44 static struct thread_pool *pool = NULL;//全局变量pool,指向线程池 45 int nowTime;//当前已走过的时间 46 //-----函数声明 47 void bubble_sort();//给TCB排序 48 void show_rr();//打印轮转队列 49 void show_tcb();//打印所有线程的信息 50 void pool_init();//初始化线程池 51 void thread_run_func(void* param);//线程里运行的函数 52 void round_robin();//时间片轮转算法的调度函数 53 int pool_destroy();//销毁线程池 54 //main 55 int main() 56 { 57 pool_init(); 58 printf("打印初始TCB:\n"); 59 show_tcb(); 60 printf("TCB按到达时间排序后:\n"); 61 bubble_sort(); 62 show_tcb(); 63 round_robin(); 64 sleep(5);//等待所有线程完成 65 pool_destroy(); 66 return 0; 67 } 68 //函数定义 69 void bubble_sort()//给TCB排序,按arriveTime升序排列 70 { 71 TCB* ptemp = NULL; 72 for(int i=0; i<THREAD_MAXN; ++i) 73 { 74 ptemp = pool->tcb; 75 while(ptemp && ptemp->next) 76 { 77 if(ptemp->arriveTime > ptemp->next->arriveTime) 78 {//交换两个节点 79 TCB *p_next = ptemp->next->next; 80 TCB *p_pre = ptemp; 81 TCB *p_pre_pre = pool->tcb; 82 if(p_pre_pre == p_pre) 83 { 84 p_pre_pre = NULL; 85 } 86 else 87 { 88 while(p_pre_pre && p_pre_pre->next != p_pre) 89 { 90 p_pre_pre = p_pre_pre->next; 91 } 92 } 93 ptemp = ptemp->next; 94 ptemp->next = p_pre; 95 p_pre->next = p_next; 96 if(p_pre_pre) 97 { 98 p_pre_pre->next = ptemp; 99 } 100 else 101 { 102 pool->tcb = ptemp; 103 } 104 } 105 ptemp = ptemp->next; 106 } 107 } 108 } 109 void show_rr()//打印轮转队列 110 { 111 printf("当前时间为:%d\n",nowTime); 112 if(pool->rrQueue.r == pool->rrQueue.f) 113 { 114 printf("目前还没有线程到达\n"); 115 } 116 else 117 { 118 printf("目前轮转队列为:\n"); 119 } 120 while(pool->rrQueue.r != pool->rrQueue.f) 121 { 122 pool->showQueue.f = (pool->showQueue.f + 1) % THREAD_MAXN; 123 pool->rrQueue.r = (pool->rrQueue.r + 1) % THREAD_MAXN; 124 pool->showQueue.tcbQueue[pool->showQueue.f] = pool->rrQueue.tcbQueue[pool->rrQueue.r]; 125 printf("%d ",pool->rrQueue.tcbQueue[pool->rrQueue.r]->thread_id); 126 } 127 while(pool->showQueue.r != pool->showQueue.f)//将队列放回 128 { 129 pool->rrQueue.f = (pool->rrQueue.f + 1) % THREAD_MAXN; 130 pool->showQueue.r = (pool->showQueue.r + 1) % THREAD_MAXN; 131 pool->rrQueue.tcbQueue[pool->rrQueue.f] = pool->showQueue.tcbQueue[pool->showQueue.r]; 132 } 133 printf("\n\n"); 134 } 135 void show_tcb()//打印所有线程的信息 136 { 137 TCB *ptemp = pool->tcb; 138 printf("打印所有线程的信息:\n"); 139 while(ptemp) 140 { 141 printf("线程%d:到达时间:%d,剩余时间:%d\n", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime); 142 ptemp = ptemp->next; 143 } 144 printf("\n"); 145 } 146 void pool_init()//初始化线程池 147 { 148 pool = (struct thread_pool*)malloc(sizeof(struct thread_pool)); 149 pthread_mutex_init(&(pool->tcb_lock), NULL);//初始为未锁住状态 150 pool->fDestroyed = 0;//线程池是否被销毁 151 pool->nowRunThread = NULL;//指向当前正在运行的线程 152 pool->nExist = 0;//现存线程 153 pool->nFinish = 0;//当前已完成的线程数 154 pool->rrQueue.r = pool->rrQueue.f = 0;//轮转队列 155 pool->showQueue.r = pool->showQueue.r = 0;//用于辅助打印的队列 156 pool->tcb = NULL; 157 //创建并初始化TCB 158 TCB* ptemp = pool->tcb; 159 srand(time(0)); 160 for(int i=0; i<THREAD_MAXN-1; ++i) 161 { 162 TCB* s = (TCB*)malloc(sizeof(TCB)); 163 s->arriveTime = rand()%9; 164 s->runTime = rand()%9+1; 165 s->thread_id = i;//编号令为0 166 s->Finished = false; 167 s->next = NULL; 168 //尾插入 169 if(!pool->tcb)//第一个节点 170 { 171 pool->tcb = s; 172 } 173 else 174 { 175 ptemp = pool->tcb; 176 while(ptemp && ptemp->next) 177 { 178 ptemp = ptemp->next; 179 } 180 ptemp->next = s; 181 } 182 } 183 //初始化信号量sem 184 ptemp = pool->tcb; 185 int i=0; 186 while(ptemp != NULL) 187 { 188 int i = ptemp->thread_id; 189 sem_init(&(pool->sem[i]), 0, 0); 190 ptemp = ptemp->next; 191 } 192 //创建线程 193 ptemp = pool->tcb; 194 pool->threadid = (pthread_t*)malloc(sizeof(pthread_t) * THREAD_MAXN); 195 while(ptemp != NULL) 196 { 197 //把ptemp作为参数传入thread_run_func() 198 int t; 199 t = pthread_create(&(pool->threadid[ptemp->thread_id]), \ 200 NULL, thread_run_func, ptemp); 201 if(!t)//线程创建成功 202 { 203 printf("线程%d创建成功!\n", ptemp->thread_id); 204 } 205 else 206 { 207 printf("线程创建失败!\n"); 208 } 209 ptemp = ptemp->next; 210 } 211 printf("线程池pool初始化完成!\n"); 212 } 213 void thread_run_func(void *param)//线程里运行的函数 214 { 215 TCB *ptemp = (TCB*)param; 216 // prtinf("线程%d开始了", ptemp->thread_id); 217 while(ptemp->runTime > 0) 218 { 219 printf("线程%d正在等待……\n", ptemp->thread_id); 220 sleep(1); 221 sem_wait(&(pool->sem[ptemp->thread_id]));//唤醒 222 printf("线程%d已被唤醒!\n",ptemp->thread_id); 223 pthread_mutex_lock(&(pool->tcb_lock));//上互斥锁 224 ptemp->runTime -= RUNTIME_SUB; 225 printf("当前时间为:%d,轮转的线程为线程%d,该线程剩余时间:%d->%d\n",\ 226 nowTime, ptemp->thread_id, ptemp->runTime+RUNTIME_SUB, ptemp->runTime<0?0:ptemp->runTime); 227 sleep(1); 228 if(ptemp->runTime <= 0)//线程已经完成 229 { 230 ++pool->nFinish; 231 ptemp->Finished = true; 232 //出队 233 pool->rrQueue.r = (pool->rrQueue.r+1)%THREAD_MAXN; 234 } 235 else 236 {//还未完成 237 //出队 238 pool->rrQueue.r = (pool->rrQueue.r+1)%THREAD_MAXN; 239 //入队 240 pool->rrQueue.f = (pool->rrQueue.f + 1) % THREAD_MAXN; 241 pool->rrQueue.tcbQueue[pool->rrQueue.f] = ptemp; 242 } 243 pthread_mutex_unlock(&(pool->tcb_lock)); 244 sleep(1); 245 } 246 pthread_exit(NULL); 247 } 248 void round_robin()//时间片轮转算法的调度函数 249 { 250 TCB *ptemp = pool->tcb; 251 while(1) 252 { 253 sleep(1); 254 pthread_mutex_lock(&(pool->tcb_lock)); 255 if(pool->nFinish == THREAD_MAXN-1)//所有线程完成 256 break; 257 while(ptemp && ptemp->arriveTime == nowTime) 258 { 259 printf("当前时间为:%d,线程%d进入轮转队列,运行时间:%d\n", \ 260 nowTime, ptemp->thread_id, ptemp->runTime); 261 pool->rrQueue.f = (pool->rrQueue.f+1)%THREAD_MAXN; 262 pool->rrQueue.tcbQueue[pool->rrQueue.f] = ptemp; 263 ptemp = ptemp->next; 264 } 265 if(pool->rrQueue.r != pool->rrQueue.f) 266 { 267 pool->nowRunThread = pool->rrQueue.tcbQueue[(pool->rrQueue.r+1)%THREAD_MAXN]; 268 printf("准备唤醒线程%d\n",pool->nowRunThread->thread_id); 269 sleep(1); 270 sem_post(&(pool->sem[pool->nowRunThread->thread_id])); 271 } 272 show_rr(); 273 ++nowTime; 274 pthread_mutex_unlock(&(pool->tcb_lock)); 275 sleep(1); 276 } 277 } 278 int pool_destroy()//销毁线程池 279 { 280 if(pool->fDestroyed)//防止重复销毁 281 return -1; 282 pool->fDestroyed = 1; 283 TCB* ptemp = pool->tcb; 284 while(ptemp) 285 { 286 pthread_join(pool->threadid[ptemp->thread_id], NULL); 287 printf("线程%d已结束\n",ptemp->thread_id); 288 ptemp = ptemp->next; 289 } 290 free(ptemp); 291 free(pool->threadid); 292 pthread_mutex_destroy(&(pool->tcb_lock)); 293 free(pool); 294 pool = NULL; 295 printf("线程池pool已被销毁!\n"); 296 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 3//线程数 13 #define RUNTIME_SUB 1//每次运行线程减去的运行时间 14 #define RUN_TIME 20//线程运行时间 15 #define INIT_FREE_BLOCK_NUM 8//内存块初始数量 16 #define INIT_FREE_BLOCK_SIZE 10//内存块初始大小 17 #define FREE_MAXN 100//最大空闲块数量 18 #define STU_NUM 20//学生数量 19 //-----结构体定义 20 typedef struct TCB//存储线程信息 21 { 22 int thread_id;//线程编号 23 int arriveTime;//线程到达时间 24 int runTime;//持续时间 25 int finishTime;//完成时间 26 int wholeTime;//周转时间 27 double weightWholeTime;//带权周转时间 28 bool Finished;//线程是否完成 29 struct TCB* next;//使用链式存储方式 30 }TCB; 31 struct tcb_queue//TCB队列定义 32 { 33 struct TCB* tcbQueue[THREAD_MAXN];//TCB指针数组 34 int r,f; 35 }; 36 struct thread_pool//线程池结构体 37 { 38 pthread_mutex_t tcb_lock;//互斥锁 39 int fDestroyed;//线程池是否被销毁 40 pthread_t *threadid;//存储线程标识符指针 41 struct TCB *nowRunThread;//指向当前正在运行的线程 42 int nFinish;//完成线程数 43 sem_t sem[THREAD_MAXN];//用于控制线程的信号量 44 struct tcb_queue rrQueue;//轮转队列 45 struct tcb_queue showQueue;//用于辅助打印的队列 46 struct TCB *tcb;//存储TCB 47 }; 48 struct free_block//空闲块结构体 49 { 50 int start;//起始位置 51 int size; 52 struct free_block *next; 53 }; 54 struct busy_block//被分配的内存块 55 { 56 int id;//编号 57 int start; 58 int size; 59 char *data;//根据需要动态分配 60 struct busy_blocl *next; 61 }; 62 struct student//储存学生信息 63 { 64 char number[9]; 65 char name[41]; 66 int name_size; 67 }; 68 //-----全局变量定义 69 static struct thread_pool *pool = NULL;//全局变量pool,指向线程池 70 int nowTime;//当前已走过的时间 71 int busy_cnt = -1;//分配块编号计数器 72 int nFree = 0;//空闲块数量 73 int nBusy = 0;//已分配块数量 74 int nameCnt = 0;//名字存储计数器 75 int numCnt = 0;//学号存储计数器 76 int ScheduleCnt = 0;//调度次数 77 struct free_block *free_queue = NULL;//储存空闲块的链表 78 struct busy_block *busy_queue = NULL;//储存已分配块的链表 79 struct student student_info[STU_NUM]; 80 //-----函数声明 81 void TCB_bubble();//给TCB排序 82 void show_rr();//打印轮转队列 83 void show_tcb();//打印所有线程的信息 84 void pool_init();//初始化线程池 85 void *thread_run_func(void* param);//线程里运行的函数 86 void round_robin();//时间片轮转算法的调度函数 87 int pool_destroy();//销毁线程池 88 void init_free();//初始化空闲块 89 struct free_block* create_free(int start, int size, struct free_block *next);//创建一个空闲块 90 struct busy_block* create_busy(int start, int size, struct busy_block *next, char *data);//创建一个已分配块 91 struct free_block * merge_free(struct free_block *f);//合并所有能够合并的空闲内存块 92 void init_student();//初始化学生的学号,姓名,采用随机生成的方法 93 void insert_busy(struct busy_block *pBusy);//尾插法插入一个分配块到链表busy_queue中 94 void insert_free(struct free_block *pFree);//尾插法插入一个空闲块到链表free_queue中 95 void delete_free(struct free_block *pFree, int size);//删除一个空闲块中被占用的部分,保留剩余部分 96 void fifo_delete_busy();//fifo算法中删除分配块 97 void lifo_delete_busy();//lifo算法中删除分配块 98 void show_free();//显示空闲块链表 99 void show_busy();//显示分配块链表 100 void FF_bubble();//按照start升序,对空闲块冒泡排序 101 void BF_bubble();//按照size升序,对空闲块冒泡排序 102 void WF_bubble();//按照size降序,对空闲块冒泡排序 103 void merge_in();//合并空闲内存块函数的入口 104 void fifo();//fifo算法调出分配块 105 void lifo();//lifo算法调出分配块 106 //main 107 int main() 108 { 109 init_student(); 110 init_free(); 111 pool_init(); 112 TCB_bubble(); 113 show_tcb(); 114 round_robin(); 115 sleep(5);//等待所有线程完成 116 pool_destroy(); 117 return 0; 118 } 119 //函数定义 120 void TCB_bubble()//给TCB排序,按arriveTime升序排列 121 { 122 TCB* ptemp = NULL; 123 for(int i=0; i<THREAD_MAXN; ++i) 124 { 125 ptemp = pool->tcb; 126 while(ptemp && ptemp->next) 127 { 128 if(ptemp->arriveTime > ptemp->next->arriveTime) 129 {//交换两个节点 130 TCB *p_next = ptemp->next->next; 131 TCB *p_pre = ptemp;//后面ptemp = ptemp->next,当前ptemp相当于pre 132 TCB *p_pre_pre = pool->tcb;//pre的pre 133 if(p_pre_pre == p_pre)//说明ptemp是头结点 134 { 135 p_pre_pre = NULL; 136 } 137 else//否则找到pre_pre所在位置 138 { 139 while(p_pre_pre && p_pre_pre->next != p_pre) 140 { 141 p_pre_pre = p_pre_pre->next; 142 } 143 } 144 //交换结点 145 ptemp = ptemp->next; 146 ptemp->next = p_pre; 147 p_pre->next = p_next; 148 if(p_pre_pre) 149 { 150 p_pre_pre->next = ptemp; 151 } 152 else 153 { 154 pool->tcb = ptemp; 155 } 156 } 157 ptemp = ptemp->next; 158 } 159 } 160 } 161 void show_rr()//打印轮转队列 162 { 163 printf("当前时间为:%d\n",nowTime); 164 if(pool->rrQueue.f == pool->rrQueue.r) 165 { 166 printf("目前还没有线程到达\n"); 167 } 168 else 169 { 170 printf("目前轮转队列为:\n"); 171 } 172 while(pool->rrQueue.f != pool->rrQueue.r) 173 { 174 pool->showQueue.f = (pool->showQueue.f + 1) % THREAD_MAXN; 175 pool->rrQueue.f = (pool->rrQueue.f + 1) % THREAD_MAXN; 176 pool->showQueue.tcbQueue[pool->showQueue.f] = pool->rrQueue.tcbQueue[pool->rrQueue.f]; 177 printf("%d ",pool->rrQueue.tcbQueue[pool->rrQueue.f]->thread_id); 178 } 179 while(pool->showQueue.r != pool->showQueue.f)//将队列放回 180 { 181 pool->rrQueue.r = (pool->rrQueue.r + 1) % THREAD_MAXN; 182 pool->showQueue.r = (pool->showQueue.r + 1) % THREAD_MAXN; 183 pool->rrQueue.tcbQueue[pool->rrQueue.r] = pool->showQueue.tcbQueue[pool->showQueue.r]; 184 } 185 printf("\n\n"); 186 } 187 void show_tcb()//打印所有线程的信息 188 { 189 TCB *ptemp = pool->tcb; 190 printf("打印所有线程的信息:\n"); 191 while(ptemp) 192 { 193 printf("线程%d:到达时间:%d,剩余时间:%d\n", ptemp->thread_id, ptemp->arriveTime, ptemp->runTime); 194 ptemp = ptemp->next; 195 } 196 printf("\n"); 197 } 198 void pool_init()//初始化线程池 199 { 200 pool = (struct thread_pool*)malloc(sizeof(struct thread_pool)); 201 pthread_mutex_init(&(pool->tcb_lock), NULL);//初始为未锁住状态 202 pool->fDestroyed = 0;//线程池是否被销毁 203 pool->nFinish = 0; 204 pool->nowRunThread = NULL;//指向当前正在运行的线程 205 pool->rrQueue.f = pool->rrQueue.r = 0;//轮转队列 206 pool->showQueue.r = pool->showQueue.r = 0;//用于辅助打印的队列 207 pool->tcb = NULL; 208 //创建并初始化TCB 209 TCB* ptemp = pool->tcb; 210 srand(time(0)); 211 for(int i=0; i<THREAD_MAXN-1; ++i) 212 { 213 TCB* s = (TCB*)malloc(sizeof(TCB)); 214 // s->arriveTime = rand()%9; 215 s->arriveTime = 0; 216 s->runTime = RUN_TIME; 217 s->thread_id = i;//编号令为0 218 s->Finished = false; 219 s->next = NULL; 220 //尾插入 221 if(!pool->tcb)//第一个节点 222 { 223 pool->tcb = s; 224 } 225 else 226 { 227 ptemp = pool->tcb; 228 while(ptemp && ptemp->next) 229 { 230 ptemp = ptemp->next; 231 } 232 ptemp->next = s; 233 } 234 } 235 //初始化信号量 236 ptemp = pool->tcb; 237 int i=0; 238 while(ptemp) 239 { 240 int i = ptemp->thread_id; 241 sem_init(&(pool->sem[i]), 0, 0); 242 ptemp = ptemp->next; 243 } 244 //创建线程 245 ptemp = pool->tcb; 246 pool->threadid = (pthread_t*)malloc(sizeof(pthread_t) * THREAD_MAXN); 247 while(ptemp) 248 { 249 //把ptemp作为参数传入thread_run_func() 250 int t; 251 t = pthread_create(&(pool->threadid[ptemp->thread_id]), \ 252 NULL, thread_run_func, ptemp); 253 if(!t)//线程创建成功 254 { 255 printf("线程%d创建成功!\n", ptemp->thread_id); 256 } 257 else 258 { 259 printf("线程创建失败!\n"); 260 } 261 ptemp = ptemp->next; 262 } 263 printf("线程池pool初始化完成!\n"); 264 } 265 void *thread_run_func(void *param)//线程里运行的函数 266 { 267 TCB *ptemp = (TCB*)param; 268 while(ptemp->runTime > 0) 269 { 270 //printf("线程%d正在等待……\n", ptemp->thread_id); 271 sleep(1); 272 sem_wait(&(pool->sem[ptemp->thread_id]));//唤醒 273 //printf("线程%d已被唤醒!\n",ptemp->thread_id); 274 pthread_mutex_lock(&(pool->tcb_lock));//上互斥锁 275 ptemp->runTime -= RUNTIME_SUB; 276 //线程操作 277 int i = numCnt; 278 int j = nameCnt; 279 struct free_block *pFree = NULL; 280 struct busy_block *pBusy = NULL; 281 if(ptemp->thread_id == 0)//store number 282 { 283 printf("将要放入内存的信息:"); 284 for(int c=0; c<8; ++c) 285 { 286 printf("%c",student_info[i].number[c]); 287 } 288 printf(",大小:8\n"); 289 printf("将所有空闲内存块紧缩\n"); 290 //紧缩 291 FF_bubble(); 292 merge_in(); 293 BF_bubble(); 294 //WF_bubble(); 295 296 show_free(); 297 pFree = free_queue; 298 pBusy = busy_queue; 299 int fEnough = 0;//内存大小是否足够 300 while(!fEnough) 301 { 302 if(pFree && pFree->size >= 8 ) 303 { 304 fEnough = 1; 305 ++numCnt; 306 pBusy = create_busy(pFree->start, 8, NULL, student_info[i].number); 307 printf("正在存储的信息:开始地址:%d, 大小:8\n",pFree->start); 308 delete_free(pFree, 8); 309 insert_busy(pBusy); 310 show_busy(); 311 break; 312 } 313 else 314 { 315 if(pFree) 316 { 317 printf("当前指向空闲内存大小不够,跳到下一块空闲内存\n"); 318 pFree = pFree->next; 319 sleep(1); 320 } 321 else 322 { 323 printf("没有足够大小的空闲内存可用,开始调度:\n"); 324 fifo(ptemp->thread_id); 325 //lifo(ptemp->thread_id); 326 printf("将所有空闲内存块紧缩\n"); 327 FF_bubble(); 328 merge_in();//紧缩 329 BF_bubble(); 330 //WF_bubble(); 331 show_free(); 332 pFree = free_queue; 333 } 334 } 335 } 336 } 337 else//store name 338 { 339 printf("将要放入内存的信息:"); 340 for(int c=0; c<student_info[j].name_size; ++c) 341 { 342 printf("%c",student_info[j].name[c]); 343 } 344 printf(",大小:%d\n",student_info[j].name_size); 345 printf("将所有空闲内存块紧缩\n"); 346 347 FF_bubble(); 348 merge_in();//紧缩 349 BF_bubble(); 350 //WF_bubble(); 351 show_free(); 352 pFree = free_queue; 353 pBusy = busy_queue; 354 int fEnough = 0; 355 while(!fEnough) 356 { 357 if(pFree && pFree->size >= student_info[j].name_size ) 358 { 359 fEnough = 1; 360 ++nameCnt; 361 pBusy = create_busy(pFree->start, student_info[j].name_size, NULL, student_info[j].name); 362 printf("正在存储的信息:开始地址:%d, 大小:%d\n", pFree->start, student_info[j].name_size); 363 delete_free(pFree, student_info[j].name_size); 364 insert_busy(pBusy); 365 show_busy(); 366 break; 367 } 368 else 369 { 370 if(pFree) 371 { 372 printf("当前指向空闲内存大小不够,跳到下一块空闲内存\n"); 373 pFree = pFree->next; 374 sleep(1); 375 } 376 else//FIFO 377 { 378 printf("没有足够大小的空闲内存可用,开始调度:\n"); 379 fifo(ptemp->thread_id); 380 //lifo(ptemp->thread_id); 381 printf("将所有空闲内存块紧缩\n"); 382 FF_bubble(); 383 merge_in();//紧缩 384 BF_bubble(); 385 //WF_bubble(); 386 show_free(); 387 pFree = free_queue; 388 } 389 } 390 } 391 } 392 //线程操作 393 //printf("当前时间为:%d,轮转的线程为线程%d,该线程剩余时间:%d->%d\n",\ 394 nowTime, ptemp->thread_id, ptemp->runTime+RUNTIME_SUB, ptemp->runTime<0?0:ptemp->runTime); 395 //sleep(1); 396 if(ptemp->runTime <= 0)//线程已经完成 397 { 398 ++pool->nFinish; 399 ptemp->Finished = true; 400 //出队 401 pool->rrQueue.f = (pool->rrQueue.f+1)%THREAD_MAXN; 402 } 403 else 404 {//还未完成 405 //出队 406 pool->rrQueue.f = (pool->rrQueue.f+1)%THREAD_MAXN; 407 //入队 408 pool->rrQueue.r = (pool->rrQueue.r + 1) % THREAD_MAXN; 409 pool->rrQueue.tcbQueue[pool->rrQueue.r] = ptemp; 410 } 411 pthread_mutex_unlock(&(pool->tcb_lock)); 412 sleep(1); 413 } 414 pthread_exit(NULL); 415 } 416 void round_robin()//时间片轮转算法的调度函数 417 { 418 TCB *ptemp = pool->tcb; 419 while(1) 420 { 421 sleep(1); 422 pthread_mutex_lock(&(pool->tcb_lock)); 423 if(pool->nFinish == THREAD_MAXN-1)//所有线程完成 424 break; 425 while(ptemp && ptemp->arriveTime == nowTime) 426 { 427 //printf("当前时间为:%d,线程%d进入轮转队列,运行时间:%d\n", \ 428 nowTime, ptemp->thread_id, ptemp->runTime); 429 pool->rrQueue.r = (pool->rrQueue.r+1)%THREAD_MAXN; 430 pool->rrQueue.tcbQueue[pool->rrQueue.r] = ptemp; 431 ptemp = ptemp->next; 432 } 433 if(pool->rrQueue.f != pool->rrQueue.r) 434 { 435 pool->nowRunThread = pool->rrQueue.tcbQueue[(pool->rrQueue.f+1)%THREAD_MAXN]; 436 //printf("准备唤醒线程%d\n",pool->nowRunThread->thread_id); 437 sleep(1); 438 sem_post(&(pool->sem[pool->nowRunThread->thread_id])); 439 } 440 //show_rr(); 441 ++nowTime; 442 pthread_mutex_unlock(&(pool->tcb_lock)); 443 sleep(1); 444 } 445 } 446 int pool_destroy()//销毁线程池 447 { 448 if(pool->fDestroyed)//防止重复销毁 449 return -1; 450 pool->fDestroyed = 1; 451 TCB* ptemp = pool->tcb; 452 while(ptemp) 453 { 454 pthread_join(pool->threadid[ptemp->thread_id], NULL); 455 printf("线程%d已结束\n",ptemp->thread_id); 456 ptemp = ptemp->next; 457 } 458 free(ptemp); 459 free(pool->threadid); 460 pthread_mutex_destroy(&(pool->tcb_lock)); 461 free(pool); 462 pool = NULL; 463 printf("线程池pool已被销毁!\n"); 464 } 465 466 //---------------------------------------------------------------------------------- 467 468 void init_free() 469 { 470 int start_address = 0; 471 struct free_block *ptemp = NULL; 472 for(int i=0; i<INIT_FREE_BLOCK_NUM; ++i) 473 { 474 struct free_block* s = create_free(start_address, INIT_FREE_BLOCK_SIZE, NULL); 475 printf("已创建起始地址为%d,大小为%d的空闲块!\n", s->start, s->size); 476 ++nFree; 477 if(!free_queue) 478 { 479 free_queue = s; 480 } 481 else 482 { 483 ptemp = free_queue; 484 while(ptemp && ptemp->next) 485 { 486 ptemp = ptemp->next; 487 } 488 ptemp->next = s; 489 } 490 start_address += INIT_FREE_BLOCK_SIZE; 491 } 492 printf("空闲内存块初始化完成!\n"); 493 show_free(); 494 } 495 struct free_block* create_free(int start, int size, struct free_block *next) 496 { 497 struct free_block *s = (struct free_block*)malloc(sizeof(struct free_block)); 498 s->start = start; 499 s->size = size; 500 s->next = next; 501 return s; 502 } 503 struct busy_block* create_busy(int start, int size, struct busy_block *next, char *data) 504 { 505 struct busy_block *s = (struct busy_block*)malloc(sizeof(struct busy_block)); 506 s->start = start; 507 s->id = ++busy_cnt; 508 s->next = NULL; 509 s->size = size; 510 s->data = (char*)malloc(sizeof(char) * size); 511 for(int i=0; i<size; ++i) 512 { 513 s->data[i] = data[i]; 514 } 515 return s; 516 } 517 void init_student() 518 { 519 srand(time(0)); 520 for(int i=0; i<STU_NUM; ++i) 521 { 522 strcpy(student_info[i].number, "201820"); 523 if(i < 10) 524 { 525 student_info[i].number[6] = '0'; 526 student_info[i].number[7] = '0' + i; 527 } 528 else 529 { 530 student_info[i].number[6] = '0' + i/10; 531 student_info[i].number[7] = '0' + i%10; 532 } 533 student_info[i].number[8] = '\0'; 534 int ran = rand()%37; 535 student_info[i].name_size = 4+ran;//拼音长度:4~40 536 for(int j=0; j<student_info[i].name_size; ++j) 537 { 538 if(i < 26) 539 { 540 student_info[i].name[j] = (char)('a' + i); 541 } 542 else 543 { 544 student_info[i].name[j] = (char)('A' + i - 26); 545 } 546 } 547 student_info[i].name[4+ran] = '\0'; 548 printf("编号:%d,姓名:%s,姓名大小:%d,学号:%s\n", i, student_info[i].name, student_info[i].name_size, student_info[i].number); 549 } 550 printf("学生信息初始化完成!\n"); 551 } 552 void FF_bubble() 553 { 554 struct free_block* ptemp = NULL; 555 if(free_queue) 556 for(int i=0; i<FREE_MAXN; ++i) 557 { 558 ptemp = free_queue; 559 while(ptemp && ptemp->next) 560 { 561 if(ptemp->start > ptemp->next->start ) 562 {//交换两个节点 563 struct free_block *p_next = ptemp->next->next; 564 struct free_block *p_pre = ptemp; 565 struct free_block *p_pre_pre = free_queue; 566 if(p_pre_pre == p_pre) 567 { 568 p_pre_pre = NULL; 569 } 570 else 571 { 572 while(p_pre_pre && p_pre_pre->next != p_pre) 573 { 574 p_pre_pre = p_pre_pre->next; 575 } 576 } 577 ptemp = ptemp->next; 578 ptemp->next = p_pre; 579 p_pre->next = p_next; 580 if(p_pre_pre) 581 { 582 p_pre_pre->next = ptemp; 583 } 584 else 585 { 586 free_queue = ptemp; 587 } 588 } 589 ptemp = ptemp->next; 590 } 591 } 592 } 593 void BF_bubble() 594 { 595 struct free_block* ptemp = NULL; 596 if(free_queue) 597 for(int i=0; i<FREE_MAXN; ++i) 598 { 599 ptemp = free_queue; 600 while(ptemp && ptemp->next) 601 { 602 if(ptemp->size > ptemp->next->size ) 603 {//交换两个节点 604 struct free_block *p_next = ptemp->next->next; 605 struct free_block *p_pre = ptemp; 606 struct free_block *p_pre_pre = free_queue; 607 if(p_pre_pre == p_pre) 608 { 609 p_pre_pre = NULL; 610 } 611 else 612 { 613 while(p_pre_pre && p_pre_pre->next != p_pre) 614 { 615 p_pre_pre = p_pre_pre->next; 616 } 617 } 618 ptemp = ptemp->next; 619 ptemp->next = p_pre; 620 p_pre->next = p_next; 621 if(p_pre_pre) 622 { 623 p_pre_pre->next = ptemp; 624 } 625 else 626 { 627 free_queue = ptemp; 628 } 629 } 630 ptemp = ptemp->next; 631 } 632 } 633 } 634 void WF_bubble() 635 { 636 struct free_block* ptemp = NULL; 637 if(free_queue!=NULL) 638 for(int i=0; i<FREE_MAXN; ++i) 639 { 640 ptemp = free_queue; 641 while(ptemp && ptemp->next) 642 { 643 if(ptemp->size < ptemp->next->size ) 644 {//交换两个节点 645 struct free_block *p_next = ptemp->next->next; 646 struct free_block *p_pre = ptemp; 647 struct free_block *p_pre_pre = free_queue; 648 if(p_pre_pre == p_pre) 649 { 650 p_pre_pre = NULL; 651 } 652 else 653 { 654 while(p_pre_pre && p_pre_pre->next != p_pre) 655 { 656 p_pre_pre = p_pre_pre->next; 657 } 658 } 659 ptemp = ptemp->next; 660 ptemp->next = p_pre; 661 p_pre->next = p_next; 662 if(p_pre_pre) 663 { 664 p_pre_pre->next = ptemp; 665 } 666 else 667 { 668 free_queue = ptemp; 669 } 670 } 671 ptemp = ptemp->next; 672 } 673 } 674 } 675 676 void insert_busy(struct busy_block *pBusy) 677 { 678 if(!busy_queue) 679 { 680 busy_queue = pBusy; 681 } 682 else 683 { 684 struct busy_block *ptemp = busy_queue; 685 while(ptemp && ptemp->next) 686 { 687 ptemp = ptemp->next; 688 } 689 ptemp->next = pBusy; 690 } 691 ++nBusy; 692 printf("完成插入分配块——开始地址:%d,大小:%d\n",pBusy->start, pBusy->size); 693 return; 694 } 695 696 void insert_free(struct free_block *pFree) 697 { 698 if(!free_queue) 699 { 700 free_queue = pFree; 701 } 702 else 703 { 704 struct free_block *ptemp = free_queue; 705 while(ptemp && ptemp->next) 706 { 707 ptemp = ptemp->next; 708 } 709 ptemp->next = pFree; 710 } 711 ++nFree; 712 printf("完成插入空闲块——开始地址:%d,大小:%d\n",pFree->start, pFree->size); 713 return; 714 } 715 void delete_free(struct free_block *pFree, int size) 716 { 717 if(!free_queue)return; 718 struct free_block *ptemp = free_queue; 719 struct free_block *pre = NULL; 720 while(ptemp) 721 { 722 if(ptemp == pFree) 723 { 724 if(pre) 725 { 726 if(pFree->size == size)//无剩余 727 { 728 --nFree; 729 pre->next = ptemp->next; 730 } 731 else 732 { 733 pre->next = create_free(pFree->start+size, pFree->size-size, ptemp->next); 734 } 735 } 736 else 737 { 738 if(pFree->size == size) 739 { 740 free_queue = ptemp->next; 741 } 742 else 743 { 744 free_queue = create_free(pFree->start+size, pFree->size-size, ptemp->next); 745 } 746 } 747 free(ptemp); 748 ptemp=NULL; 749 break; 750 } 751 pre = ptemp; 752 ptemp = ptemp->next; 753 } 754 return; 755 } 756 void fifo_delete_busy() 757 { 758 if(busy_queue) 759 { 760 struct busy_block *ptemp = busy_queue; 761 busy_queue = busy_queue->next; 762 free(ptemp); 763 ptemp=NULL; 764 --nBusy; 765 } 766 else 767 { 768 printf("无分配块\n"); 769 } 770 } 771 void lifo_delete_busy() 772 { 773 if(busy_queue) 774 { 775 struct busy_block *ptemp = busy_queue; 776 struct busy_block *pre = NULL; 777 while(ptemp && ptemp->next) 778 { 779 pre = ptemp; 780 ptemp = ptemp->next; 781 } 782 if(!pre) 783 { 784 busy_queue = NULL; 785 } 786 else 787 { 788 pre->next = NULL; 789 } 790 free(ptemp); 791 ptemp = NULL; 792 --nBusy; 793 } 794 else 795 { 796 printf("无分配块\n"); 797 } 798 return; 799 } 800 void show_free() 801 { 802 if(free_queue) 803 { 804 struct free_block *ptemp = free_queue; 805 printf("显示空闲块:\n"); 806 while(ptemp) 807 { 808 printf("————开始:%d,大小:%d\n",ptemp->start, ptemp->size); 809 ptemp = ptemp->next; 810 } 811 printf("\n"); 812 } 813 else 814 { 815 printf("当前无空闲块\n"); 816 } 817 return; 818 } 819 void show_busy() 820 { 821 if(busy_queue) 822 { 823 struct busy_block *ptemp = busy_queue; 824 printf("显示已分配块:\n"); 825 while(ptemp) 826 { 827 printf("—————————序号:%d,开始:%d,大小:%d,数据:",ptemp->id, ptemp->start, ptemp->size); 828 for(int i=0; i<ptemp->size; ++i) 829 { 830 printf("%c",ptemp->data[i]); 831 } 832 printf("\n"); 833 ptemp = ptemp->next; 834 } 835 printf("\n"); 836 } 837 else 838 { 839 printf("当前无分配块\n"); 840 } 841 return; 842 } 843 void merge_in() 844 { 845 free_queue = merge_free(free_queue); 846 printf("紧缩完成\n"); 847 return; 848 } 849 struct free_block * merge_free(struct free_block *f) 850 { 851 if(f && f->next) 852 { 853 f->next = merge_free(f->next); 854 if(f->next && (f->start + f->size == f->next->start)) 855 { 856 struct free_block *p = f->next; 857 f->next = p->next; 858 f->size += p->size; 859 free(p); 860 p=NULL; 861 } 862 } 863 return f; 864 } 865 void fifo(int thread_id) 866 { 867 if(busy_queue) 868 { 869 printf("————————————————————————————————被调出的信息:序号:%d,开始地址:%d,大小:%d, 数据:", \ 870 busy_queue->id, busy_queue->start, busy_queue->size); 871 for(int k=0; k<busy_queue->size; ++k) 872 { 873 printf("%c",busy_queue->data[k]); 874 } 875 printf("————————————————————————————————\n"); 876 printf("————————————————————————————————调度次数:%d,当前线程号:%d————————————————————————————————\n",++ScheduleCnt,thread_id); 877 struct free_block *pFree = create_free(busy_queue->start, busy_queue->size, NULL); 878 insert_free(pFree); 879 fifo_delete_busy(); 880 } 881 else 882 { 883 printf("无分配块,无法调出\n"); 884 } 885 return; 886 } 887 void lifo(int thread_id) 888 { 889 if(busy_queue) 890 { 891 struct busy_block *ptemp = busy_queue; 892 while(ptemp && ptemp->next) 893 { 894 ptemp = ptemp->next; 895 } 896 printf("————————————————————————————————被调出的信息:序号:%d,开始地址:%d,大小:%d, 数据:", \ 897 ptemp->id, ptemp->start, ptemp->size); 898 for(int k=0; k<ptemp->size; ++k) 899 { 900 printf("%c", ptemp->data[k]); 901 } 902 printf("————————————————————————————————\n"); 903 printf("————————————————————————————————调度次数:%d,当前线程号:%d————————————————————————————————\n",++ScheduleCnt,thread_id); 904 struct free_block *pFree = create_free(ptemp->start, ptemp->size, NULL); 905 insert_free(pFree); 906 lifo_delete_busy(); 907 } 908 else 909 { 910 printf("无分配块,无法调出\n"); 911 } 912 return; 913 }