读写锁(二)

一、实验项目

问题描述】程序 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;              // 余票数,初始化为 1000
    pthread_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]);
        else
            pthread_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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值