Loading... 1.多线程的一个demo ```cpp /* 使用多线程实现买票的案例。 有3个窗口,一共是100张票。 */ #include <stdio.h> #include <pthread.h> #include <unistd.h> // 全局变量,所有的线程都共享这一份资源。 int tickets = 100;//放到sellticket里面的话 就是每个线程卖100张门票!! void * sellticket(void * arg) { // 卖票 tickets时临界资源 while后面的时临时区 while(tickets > 0) { usleep(6000);//单位微秒 printf("%ld 正在卖第 %d 张门票\\n", pthread_self(), tickets); tickets--;//线程并发去执行 抢CPU执行资格 } return NULL; } int main() { // 创建3个子线程 要执行的内容一样 就用同一个callback: sellticket //main线程啥也不干 只是负责对子线程的回收 pthread_t tid1, tid2, tid3; pthread_create(&tid1, NULL, sellticket, NULL); pthread_create(&tid2, NULL, sellticket, NULL); pthread_create(&tid3, NULL, sellticket, NULL); // 回收子线程的资源,阻塞 线程没结束会阻塞在这 pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); // 设置线程分离。 不使用pthread_join 使用pthread_detach也可以 // pthread_detach(tid1); // pthread_detach(tid2); // pthread_detach(tid3); pthread_exit(NULL); // 退出主线程 不影响子线程 return 0; } /* [haozheng@hzlinb30 practice]$ ./3_8_selltickets 140063953090304 正在卖第 100 张门票 140063944697600 正在卖第 100 张门票 140063936304896 正在卖第 98 张门票 140063953090304 正在卖第 97 张门票 140063944697600 正在卖第 97 张门票 140063936304896 正在卖第 95 张门票 140063944697600 正在卖第 3 张门票 140063936304896 正在卖第 2 张门票 140063953090304 正在卖第 1 张门票 140063944697600 正在卖第 0 张门票 140063936304896 正在卖第 -1 张门票 */ ``` 分析: 这里为啥要加上 usleep(6000); 因为cpu执行的非常快,这里usleep就是让当前的线程休眠,这样好让出cpu。 主要是为了演示效果 一定要在主线程结束之前运行子线程,所以要加上join等待 在打印sellticket函数的时候,会出现两种异常情况: case1: 两个线程会出现卖同一张票的情况, printf("%ld 正在卖第 %d 张门票\\n", pthread\_self(), tickets); //打印的都是100 因为当有两个线程thread1和thread2同时进入到 while(tickets > 0) {之后,thread1刚好走到printf这一步之后,资源就被thread2拿走了,thread2在打印print之前,thread1始终都还没拿到锁 case2: 线程会出现卖负数票的情况,同case1一样,当printf为0的时候,刚好两个线程都在printf这一行,然后两个线程都去执行 - -这个操作,就会导致出现负数这种情况,也就是卖负数张票这种情况 Note: 为了测试等待,能否直接使用for循环而不使用join来进行等待 ```cpp int i; for(i = 0; i < 1000000; i++) { ; // 延时 } ``` 子线程得到了运行,因为主线程需要的时间比较长,而时间片不够,所以其它线程就运行了,等其它线程执行完后,又返回了主线程继续进行执行,直至主线程结束。 1. 对int变量赋值的操作是原子的吗? —> 不是 [对int变量赋值的操作是原子的吗?](https://www.zhihu.com/question/27026846) 可以进行测试,当两个线程通知对一个共享变量进行+1的话,最终也许并不是加了2,而是只加了1 1. 多CPU如何进行调度  1. sleep\_for函数的使用 ```cpp 1)使用说明 std::this_thread::sleep_for函数是C11的休眠函数,表示当前线程休眠一段时间,休眠期间不与其他线程竞争CPU,根据线程需求,等待若干时间。 由于是一个跨平台的函数,因此在代码中大量应用,避免了在不同平台之间所以通过宏定义编译问题。在windows下,可以简单替代Sleep, 在Linux下,替代usleep 2)调用例子 头文件定义:#include <thread> std::this_thread::sleep_for(std::chrono::milliseconds(50));//睡眠50毫秒 参考: <https://blog.51cto.com/fengyuzaitu/2565089> // this_thread::sleep_for example #include <iostream> // std::cout, std::endl #include <thread> // std::this_thread::sleep_for #include <chrono> // std::chrono::seconds int main() { std::cout << "countdown:\\n"; for (int i=10; i>0; --i) { std::cout << i << std::endl; std::this_thread::sleep_for (std::chrono::seconds(1)); } std::cout << "Lift off!\\n"; return 0; } ``` 基础知识入门与总结 [多线程总结vedio](https://www.notion.so/vedio-7b8191bba26f491e8beee9574ec56fd4?pvs=21) [STL的容器多线程问题](https://www.notion.so/STL-2e80589e3c07408282bcf9eeb93d0fa4?pvs=21) [线程安全](https://www.notion.so/77670c081e9d405db3669d2b9995d392?pvs=21) [多线程访问文件导致的问题](https://www.notion.so/8dcebaa60a9e4812afb4e1be78effa6e?pvs=21) [各种锁的使用](https://www.notion.so/fb481496652a497588d21efff2ef4505?pvs=21) [枚举在多线程中的应用](https://www.notion.so/b447ebbbb51b49278d90704d3fb1d5ad?pvs=21) [lamber表达式在多线程中的坑](https://www.notion.so/lamber-b441f89a0f8848f7b3c890a1b177b425?pvs=21) [单核和多核执行下面这段代码区别](https://www.notion.so/4e18e251f6dc476dba33566f23d6e8e9?pvs=21) [条件变量](https://www.notion.so/68b7eb297b1c4da9948667568de9eda1?pvs=21) [**C++ - 线程安全的std::cout**](https://www.notion.so/C-std-cout-0877a61fa66f405dad7f8f6881537b46?pvs=21) 最后修改:2025 年 07 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏