linux多线程实验:模拟售票系统

主要用到函数:

#include <pthread.h>

pthread_create(&tid[i], nullptr, Sale_ticket, static_cast<void*>(&i));//创建线程
pthread_join(tid[i], nullptr);//等待线程终止
pthread_mutex_t mv_num = PTHREAD_MUTEX_INITIALIZER;//初始化锁
pthread_mutex_lock(&mv_num);//上锁
pthread_mutex_unlock(&mv_num);//开锁
pthread_mutex_destroy(&mv_num);//销毁锁
#include <time.h>

time_t timep;
time (&timep); //获取系统时间
ctime (&timep); //转换成字符串
#include <unistd.h>

sleep()

 

程序模拟了4个窗口,一起卖20张票。

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 #include <time.h>
 5 #define WINDOW_NUM 4
 6 int total = 20;
 7 pthread_mutex_t mv_num = PTHREAD_MUTEX_INITIALIZER;
 8 
 9 void* Sale_ticket(void *id)
10 {
11     int Window_id = *static_cast<int*>(id) + 1;
12     time_t timep;
13     time (&timep);
14     printf("Window %d starts saling tickets AT %s", Window_id, ctime(&timep));
15     while(1)
16     {
17         pthread_mutex_lock(&mv_num);
18         if (total <= 0) {
19             pthread_mutex_unlock(&mv_num);
20             break;
21         }
22         time (&timep);
23         printf("Window %d Sales ticket %d AT %s", Window_id, total--, ctime(&timep));
24         pthread_mutex_unlock(&mv_num);
25         sleep(Window_id);
26     }
27     return nullptr;
28 }
29 
30 int main()
31 {
32     pthread_t tid[WINDOW_NUM];
33     int i = 0;
34     for (i = 0; i < WINDOW_NUM; ++i)
35     {
36         pthread_create(&tid[i], nullptr, Sale_ticket, static_cast<void*>(&i));
37         sleep(1);
38     }
39     for (i = 0; i < WINDOW_NUM; ++i)
40     {
41         pthread_join(tid[i], nullptr);
42     }
43     pthread_mutex_destroy(&mv_num);
44     return 0;
45 }

实验结果如图:

一些结论:

1、网上对linux下sleep()休眠的是整个进程还是某一个线程的答案不统一,在我的测试环境下(ubuntu 16.04 LTS),发现sleep休眠的是单独线程。理由:

结果中,窗口1每1秒卖一张票,窗口2每2秒卖1张票,主线程每1秒创建一个新窗口,相互之间时间间隔不影响。

2、printf线程安全,cout线程不安全。测试发现cout输出时,线程之间相互干扰打断。

3、ctime (&timep) 转换过来的字符串,自带换行符。

 

---------------------------------------------------------------------------

带补票的售票系统。

主要用到条件变量:

#include <pthread.h>

pthread_cond_t cv = PTHREAD_COND_INITIALIZER;//初始化条件变量
pthread_cond_wait(&cv, &mv_num);//等待条件变量
pthread_cond_broadcast(&cv); //群发版的pthread_cond_signal(&cv);
pthread_cond_destroy(&cv);//销毁一个条件变量

代码:

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 #include <time.h>
 5 #define WINDOW_NUM 4
 6 int total = 0;
 7 bool flag;
 8 pthread_mutex_t mv_num = PTHREAD_MUTEX_INITIALIZER;
 9 pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
10 
11 void* Sale_ticket(void *id)
12 {
13     int Window_id = *static_cast<int*>(id) + 1;
14     time_t timep;
15     time (&timep);
16     printf("Window %d starts saling tickets AT %s", Window_id, ctime(&timep));
17     while(1)
18     {
19         pthread_mutex_lock(&mv_num);
20         while (flag && total <= 0) {
21             pthread_cond_wait(&cv, &mv_num);
22         }
23         if (total <= 0) {
24             pthread_mutex_unlock(&mv_num);
25             break;
26         }
27         time (&timep);
28         printf("Window %d Sales ticket %d AT %s", Window_id, total--, ctime(&timep));
29         pthread_mutex_unlock(&mv_num);
30         sleep(Window_id);
31     }
32     return nullptr;
33 }
34 
35 int main()
36 {
37     pthread_t tid[WINDOW_NUM];
38     int i = 0;
39     int k = 2;
40     flag = true;
41     for (i = 0; i < WINDOW_NUM; ++i)
42     {
43         pthread_create(&tid[i], nullptr, Sale_ticket, static_cast<void*>(&i));
44         sleep(1);
45     }
46     while (k--) {
47         sleep(10);
48         pthread_mutex_lock(&mv_num);
49         total += 10;
50         time_t timep;
51         time (&timep);
52         printf("*********Add 10 tickets*********** AT %s", ctime(&timep));
53         pthread_cond_broadcast(&cv);
54         pthread_mutex_unlock(&mv_num);
55     }
56     flag = false;
57     for (i = 0; i < WINDOW_NUM; ++i)
58     {
59         pthread_join(tid[i], nullptr);
60     }
61     pthread_mutex_destroy(&mv_num);
62     pthread_cond_destroy(&cv);
63     return 0;
64 }

结果:

讨论:

主要是关于

while (flag && total <= 0) {
        pthread_cond_wait(&cv, &mv_num);
}

这里用的是while而不是if。while相比if,可能在效率上不高,但是保证了稳定和安全。网上有很多解释。

主要是两个原因:(1)it was not interrupted; (2)due to spurious wakeup.

第一点说的是一些中断或者非人为因素而导致的返回信号没被正确接受。

第二点说的就是传说中的“惊群效应”。

转载于:https://www.cnblogs.com/Zzz-y/p/9077420.html

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值