一、實驗項目
【問題描述】程序 trainticket 中,有 100 個線程,其中 90 個線程是查余票數量的,只有 10 個線程搶票,每個線程一次買 10 張票。初始狀態下一共有 1000 張票。因此執行完畢后,還會剩下 900 張票。
程序 trainticket 在運行的時候需要傳入參數,即:
- 參數 0:表示不加任何鎖
- 參數 1:表示使用讀寫鎖
- 參數 2:表示使用互斥量
測試代碼:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>struct Ticket
{int remain; // 余票數,初始化為 1000pthread_rwlock_t rwlock; // 讀寫鎖pthread_mutex_t mlock; // 互斥鎖,主要是為了和讀寫鎖進行對比
}ticket;// 通過命令行傳參數來取得這個值,用來控制到底使用哪一種鎖
// 0:不加鎖 1:加讀寫鎖 2:加互斥鎖
int lock = 0;void* query(void* arg) //查票線程
{int name = (int)arg;sleep(rand() % 5 + 1);if (lock == 1)pthread_rwlock_rdlock(&ticket.rwlock); // 讀模式加鎖else if (lock == 2)pthread_mutex_lock(&ticket.mlock);int remain = ticket.remain;sleep(1);printf("%03d query: %d\n", name, remain);if (lock == 1)pthread_rwlock_unlock(&ticket.rwlock);else if (lock == 2)pthread_mutex_unlock(&ticket.mlock);return NULL;
}void* buy(void* arg) // 搶票線程
{int name = (int)arg;if (lock == 1)pthread_rwlock_wrlock(&ticket.rwlock); // 寫模式加鎖else if (lock == 2)pthread_mutex_lock(&ticket.mlock);int remain = ticket.remain;remain -= 10; // 一次買 10 張票sleep(1);ticket.remain = remain;printf("%03d buy 10 tickets\n", name);if (lock == 1)pthread_rwlock_unlock(&ticket.rwlock);else if (lock == 2)pthread_mutex_unlock(&ticket.mlock);sleep(rand() % 5 + 2);return NULL;
}int main(int argc, char* argv[])
{lock = 0;if (argc >= 2) lock = atoi(argv[1]);int names[100];pthread_t tid[100];int i;for (i = 0; i < 100; ++i) names[i] = i;ticket.remain = 1000;printf("remain ticket = %d\n", ticket.remain);pthread_rwlock_init(&ticket.rwlock, NULL);pthread_mutex_init(&ticket.mlock, NULL);for (i = 0; i < 100; ++i) {if (i % 10 == 0)pthread_create(&tid[i], NULL, buy, (void*)names[i]);elsepthread_create(&tid[i], NULL, query, (void*)names[i]);}for (i = 0; i < 100; ++i) pthread_join(tid[i], NULL);pthread_rwlock_destroy(&ticket.rwlock);pthread_mutex_destroy(&ticket.mlock);printf("remain ticket = %d\n", ticket.remain);return 0;
}
?
輸出結果:不加鎖
sunbin@sunbin-virtual-machine:~$ ./a.out 0
remain ticket = 1000
010 buy 10 tickets
020 buy 10 tickets
030 buy 10 tickets
000 buy 10 tickets
050 buy 10 tickets
060 buy 10 tickets
070 buy 10 tickets
080 buy 10 tickets
090 buy 10 tickets
040 buy 10 tickets
021 query: 990
036 query: 990
017 query: 990
031 query: 990
011 query: 990
005 query: 1000
043 query: 990
058 query: 990
063 query: 990
067 query: 990
069 query: 990
071 query: 990
075 query: 990
082 query: 990
084 query: 990
096 query: 990
025 query: 990
022 query: 990
014 query: 990
024 query: 990
019 query: 990
012 query: 990
007 query: 990
047 query: 990
048 query: 990
052 query: 990
061 query: 990
062 query: 990
064 query: 990
042 query: 990
068 query: 990
074 query: 990
076 query: 990
098 query: 990
091 query: 990
029 query: 990
027 query: 990
026 query: 990
035 query: 990
033 query: 990
023 query: 990
015 query: 990
002 query: 990
016 query: 990
004 query: 990
008 query: 990
045 query: 990
049 query: 990
055 query: 990
066 query: 990
073 query: 990
079 query: 990
083 query: 990
085 query: 990
089 query: 990
034 query: 990
001 query: 990
032 query: 990
018 query: 990
009 query: 990
006 query: 990
046 query: 990
051 query: 990
056 query: 990
059 query: 990
065 query: 990
078 query: 990
088 query: 990
093 query: 990
094 query: 990
095 query: 990
097 query: 990
038 query: 990
037 query: 990
028 query: 990
003 query: 990
013 query: 990
044 query: 990
053 query: 990
054 query: 990
057 query: 990
072 query: 990
077 query: 990
081 query: 990
041 query: 990
086 query: 990
087 query: 990
092 query: 990
099 query: 990
039 query: 990
remain ticket = 990
輸出結果:讀寫鎖
sunbin@sunbin-virtual-machine:~$ ./a.out 1
remain ticket = 1000
010 buy 10 tickets
008 query: 990
003 query: 990
015 query: 990
019 query: 990
029 query: 990
001 query: 990
054 query: 990
055 query: 990
059 query: 990
067 query: 990
064 query: 990
068 query: 990
073 query: 990
079 query: 990
082 query: 990
088 query: 990
009 query: 990
004 query: 990
012 query: 990
023 query: 990
024 query: 990
021 query: 990
018 query: 990
042 query: 990
043 query: 990
047 query: 990
057 query: 990
061 query: 990
065 query: 990
058 query: 990
066 query: 990
072 query: 990
074 query: 990
092 query: 990
097 query: 990
006 query: 990
011 query: 990
013 query: 990
014 query: 990
026 query: 990
028 query: 990
022 query: 990
031 query: 990
033 query: 990
035 query: 990
036 query: 990
039 query: 990
044 query: 990
051 query: 990
063 query: 990
071 query: 990
077 query: 990
081 query: 990
084 query: 990
089 query: 990
005 query: 990
007 query: 990
017 query: 990
025 query: 990
032 query: 990
037 query: 990
041 query: 990
046 query: 990
052 query: 990
056 query: 990
062 query: 990
076 query: 990
087 query: 990
091 query: 990
093 query: 990
094 query: 990
096 query: 990
002 query: 990
016 query: 990
027 query: 990
034 query: 990
038 query: 990
045 query: 990
048 query: 990
049 query: 990
053 query: 990
069 query: 990
075 query: 990
078 query: 990
083 query: 990
085 query: 990
086 query: 990
095 query: 990
098 query: 990
099 query: 990
030 buy 10 tickets
040 buy 10 tickets
000 buy 10 tickets
050 buy 10 tickets
060 buy 10 tickets
070 buy 10 tickets
080 buy 10 tickets
090 buy 10 tickets
020 buy 10 tickets
remain ticket = 900
輸出結果:互斥鎖
sunbin@sunbin-virtual-machine:~$ ./a.out 2
remain ticket = 1000
010 buy 10 tickets
011 query: 990
030 buy 10 tickets
050 buy 10 tickets
040 buy 10 tickets
060 buy 10 tickets
070 buy 10 tickets
080 buy 10 tickets
000 buy 10 tickets
090 buy 10 tickets
005 query: 910
016 query: 910
020 buy 10 tickets
021 query: 900
032 query: 900
044 query: 900
055 query: 900
056 query: 900
001 query: 900
064 query: 900
067 query: 900
068 query: 900
073 query: 900
079 query: 900
082 query: 900
088 query: 900
007 query: 900
012 query: 900
014 query: 900
019 query: 900
022 query: 900
002 query: 900
024 query: 900
039 query: 900
048 query: 900
037 query: 900
058 query: 900
059 query: 900
061 query: 900
065 query: 900
066 query: 900
072 query: 900
074 query: 900
097 query: 900
093 query: 900
008 query: 900
004 query: 900
003 query: 900
015 query: 900
023 query: 900
026 query: 900
029 query: 900
042 query: 900
034 query: 900
035 query: 900
041 query: 900
028 query: 900
043 query: 900
052 query: 900
063 query: 900
071 query: 900
077 query: 900
081 query: 900
084 query: 900
089 query: 900
006 query: 900
009 query: 900
018 query: 900
025 query: 900
047 query: 900
031 query: 900
038 query: 900
036 query: 900
053 query: 900
057 query: 900
062 query: 900
076 query: 900
087 query: 900
096 query: 900
098 query: 900
099 query: 900
094 query: 900
013 query: 900
017 query: 900
027 query: 900
033 query: 900
046 query: 900
045 query: 900
049 query: 900
051 query: 900
054 query: 900
069 query: 900
075 query: 900
078 query: 900
083 query: 900
085 query: 900
086 query: 900
095 query: 900
092 query: 900
091 query: 900
remain ticket = 900
二、參考資料:
1. 2-讀寫鎖 rwlock