读写锁(二)
一、實驗項目
【問題描述】程序 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
總結