数据结构+操作系统实验代码

目录:

实验一:

邻接表:

 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 }
View Code

邻接矩阵:

 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 }
View Code

实验二:

BFS+DFS(邻接表):

  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 }
View Code

实验三:

最小生成树(邻接表):

Prim和Kruskal:

  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 }
View Code

实验四:

最短路径

Dijkstra:

  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             
View Code

实验五

最短路径

Floyd:

 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 }
View Code

 

 

实验六:图的综合应用

 

  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
  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 }
View Code

实验八:

多线程

哲学家就餐

 问题:

  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 }
View Code

多线程共享资源:多个线程共享变量sum

 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 }    
View Code

 实验九:  

1、设计并实现操作系统读者写者问题读者优先算法。

只要有一个读者在读,其他读者就无需等待

为什么?因为如果有读者了,说明在读写者的竞争中,读者得到了资源,后面来的读者就可以直接读了

2、设计并实现操作系统读者写者问题写者优先算法。

放一起:

  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 }
View Code

末尾有“2”的为写者优先的程序运行结果

 实验十:

  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 }
RR

 

  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 }
时间片轮转法调度

 

      

posted @ 2020-07-12 16:45  幻想Elapse  阅读(205)  评论(0编辑  收藏  举报