实现功能
功能:实现Peterson算法
题目来源:《操作系统概念第9版》P178页 6.3
详细功能:实现Peterson算法,连续输出数字观察是否出现乱序
源代码
Peterson.c
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<time.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int count = 0;
int flag[2] = {0, 0}; // Mark the state of each thread
int victim;
int num = 0;
void lock(int thread_id) {
int i = thread_id;
victim = i ^ 1; // Point to another thread
flag[i] = 1; // The current thread is locked
while(flag[victim] == 1) { // When another thread is locked, wait
if(victim == thread_id) { // The other side is also waiting for them, to avoid deadlock
continue; // Reset wait
}
}
}
void unlock(int thread_id) {
flag[thread_id] = 0; // unlock
}
void* fun_linux(void* args) {
pthread_mutex_lock(&mutex);
for(int i = 0; i < 50000; i++) {
count++;
if(count % 10000 == 0) printf("\n");
if(count % 1000 == 0) printf("%d ", count);
}
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void* fun_petreson(void* args) {
lock(num);
for(int i = 0; i < 50000; i++) {
count++;
if(count % 10000 == 0) printf("\n");
if(count % 1000 == 0) printf("%d ", count);
}
num = num ^ 1;
unlock(num ^ 1);
pthread_exit(NULL);
}
int main()
{
clock_t start, end;
pthread_t threads[2];
pthread_mutex_init(&mutex, NULL); // Mutex initialization
start = clock();
int s;
for(int i = 0; i < 2; i++) { // Loop creation thread
s = pthread_create(&threads[i], NULL, fun_linux, NULL);
if(s) {
printf("Thread creat error\n");
exit(1);
}
pthread_join(threads[i], NULL);
}
end = clock();
double RunningTime = (double)(end - start)/CLOCKS_PER_SEC * 1000;
printf("Linux_Lock running time is %.3f ms\n\n", RunningTime);
pthread_mutex_destroy(&mutex); // The mutex is destroyed
sleep(5);
count = 0;
start = clock();
for(int i = 0; i < 2; i++) { // Loop creation thread
s = pthread_create(&threads[i], NULL, fun_petreson, NULL);
if(s) {
printf("Thread creat error\n");
exit(1);
}
pthread_join(threads[i], NULL);
}
end = clock();
RunningTime = (double)(end - start)/CLOCKS_PER_SEC * 1000;
printf("Linux_Petreson running time is %.3f ms\n", RunningTime);
return 0;
}
Makefile
cc = gcc
filename = Peterson
src1 = $(filename).c
out = $(filename)
$(out): $(src1)
$(cc) -o $(out) $(src1) -lpthread
run:
./$(out)
clean:
rm -rf $(out)
如何使用
make # 编译
./Peterson # 运行可执行文件