面試題分享-多線程順序打印奇偶數

目錄

1.題目詳情

2.解題思路

2.1.分析題目

2.2.解析思路

3.代碼實現

4.運行結果


1.題目詳情

? ? ? ? 昨天刷抖音,遇到一個面試題,描述如下:

? ? ? ? 請使用兩個線程,分別順序交替打印奇數和偶數,直到10為止。例如有兩個線程,分別為線程1和線程2,線程1首先打印數字1,然后線程2打印數字2,接著線程1再打印數字3,線程2再打印數字4,依次交替運行直到10為止。

2.解題思路

2.1.分析題目

? ? ? ? 乍一看題目很簡單,但是其中涉及了多線程、鎖、線程同步等知識點,如果簡單的使用互斥鎖或者其他的鎖恐怕不會是最好的答案。

2.2.解析思路

? ? ? ? 現在無非要解決兩個問題,第一個問題:線程1需要打印奇數而線程2需要打印偶數;第二個問題:線程1執行完之后需要跳轉到線程2執行。這其中就涉及到了線程切換如何實現,關鍵需要解決第二個問題。

? ? ? ? 拋開第一個問題不談,要解決線程切換的問題,我們先使用互斥鎖實現,采用一個全局變量(標記位)控制兩個線程的執行順序。如果標記位等于某一個值則執行線程1,執行完將標記位置為另一個狀態值,線程2獲取到標記位發生改變,則執行線程2,依次類推。

? ? ? ? 提到這種解題思路,這不就是信號量操作嗎,線程1先執行,然后釋放信號,線程2阻塞等待信號,然后執行。

3.代碼實現

互斥鎖代碼實現:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t lock;
#define TARGET 10
int turn = 1;  //1: 表示輪到打印奇數 2: 表示輪到打印偶數//打印奇數
void* print_odd(void* arg) {int num = 1;while (num <= TARGET) {pthread_mutex_lock(&lock);while (turn != 1) {pthread_mutex_unlock(&lock);continue;}printf("thread id:%lu, num:%d\n", pthread_self(), num);turn = 2;pthread_mutex_unlock(&lock);num += 2;}return NULL;
}//打印偶數
void* print_even(void* arg) {int num = 2;while (num <= TARGET) {pthread_mutex_lock(&lock);while (turn != 2) {pthread_mutex_unlock(&lock);continue;}printf("thread id:%lu, num:%d\n", pthread_self(), num);turn = 1;pthread_mutex_unlock(&lock);num += 2;}return NULL;
}int main() {//初始化鎖pthread_mutex_init(&lock, NULL);pthread_t odd_thread, even_thread;//創建線程pthread_create(&odd_thread, NULL, print_odd, NULL);pthread_create(&even_thread, NULL, print_even, NULL);//等待線程結束pthread_join(odd_thread, NULL);pthread_join(even_thread, NULL);//銷毀鎖pthread_mutex_destroy(&lock);return 0;
}

? ? ? ? 打印奇數線程首先運行,turn為標記位,如果標記位為1則打印奇數并修改標記位,如果標記位不是1則釋放鎖等待;打印偶數線程后運行,標記位初始狀態為1,等待標記位,待標記位修改之后,打印偶數。

信號量代碼實現:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>#define TARGET 10/* 奇數信號量 */
sem_t sem_odd;
/* 偶數信號量 */
sem_t sem_even;static void *print_odd() {int num = 1;while (num <= TARGET) {sem_wait(&sem_odd);printf("thread id:%lu, num:%d\n", pthread_self(), num);num += 2;sem_post(&sem_even);}return NULL;
}static void *print_even() {int num = 2;while (num <= TARGET) {sem_wait(&sem_even);printf("thread id:%lu, num:%d\n", pthread_self(), num);sem_post(&sem_odd);num += 2;}return NULL;
}int main()
{int ret = 0;//將奇數信號量初始值設為1 首先運行ret = sem_init(&sem_odd, 0, 1); if (ret != 0) {printf("init sem_odd failed, ret:%d\n.", ret);return -1;}//將偶數信號量初始值設為0 其次運行ret = sem_init(&sem_even, 0, 0);if (ret != 0) {printf("init sem_even failed, ret:%d\n.", ret);return -1;}pthread_t thread1 = 0;pthread_t thread2 = 0;pthread_create(&thread1, NULL, print_odd, NULL);pthread_create(&thread2, NULL, print_even, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);return 0;
}

? ? ? ? 設置兩個信號量,一個信號量用于控制打印奇數,一個信號量用于控制打印偶數;奇數信號量初始化為1,首先運行,偶數信號量初始化為0,其次運行;打印奇數線程運行完之后發送偶數信號量運行信號,偶數信號量運行完成之后發送奇數信號量運行信號,依次交替打印奇偶數。

4.運行結果

? ? ? ? 兩個線程依次交替打印奇偶數:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74494.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74494.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74494.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模型 杜根定律

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思維模型目錄。信心>能力、行動導向、未來時態。 1 杜根定律的應用 1.1 公共政策博弈——底特律市長杜根的保險改革攻堅戰 核心挑戰&#xff1a;底特律市長Mike Duggan面臨汽車保險費率畸高導致居民陷入貧困循環的…

關于在vscode中的Linux 0.11 應用程序項目的生成和運行

首先我們需要需要查看鏡像文件 查看軟盤鏡像文件 floppyb.img 中的內容 在 VSCode 的“Terminal”菜單中選擇“Run Build Task...”&#xff0c;會在 VSCode 的頂部中間位置彈出一個 可以執行的 Task 列表&#xff0c;選擇其中的“打開 floppyb.img”后會使用 Floppy Editor …

使用CSS3實現炫酷的3D視差滾動效果

使用CSS3實現炫酷的3D視差滾動效果 這里寫目錄標題 使用CSS3實現炫酷的3D視差滾動效果項目概述核心技術實現1. 3D空間的創建2. 視差層級設置3. 動畫效果實現流星動畫月亮發光效果 技術難點與解決方案1. 層級重疊問題2. 性能優化3. 響應式適配 開發心得總結 項目概述 在這個項目…

作業12 (2023-05-15 指針概念)

第1題/共11題【單選題】 關于指針的概念,錯誤的是:( ) A.指針變量是用來存放地址的變量 B.指針變量中存的有效地址可以唯一指向內存中的一塊區域 C.野指針也可以正常使用 D.局部指針變量不初始化就是野指針 回答正確 答案解析: A:正確,指針變量中存儲的是一個地址,指…

【ESP32S3】esp32獲取串口數據并通過http上傳到前端

通過前面的學習&#xff08;前面沒發過&#xff0c;因為其實就是跑它的demo&#xff09;了解到串口配置以及開啟線程實現功能的工作流程&#xff0c;與此同時還有esp32作為STA節點&#xff0c;將數據通過http發送到服務器。 將這兩者聯合 其實是可以得到一個&#xff1a;esp32獲…

《鴻蒙攜手AI:解鎖智慧出行底層邏輯》

在科技飛速發展的當下&#xff0c;智慧出行成為人們對未來交通的美好期許&#xff0c;而鴻蒙系統與人工智能的深度融合&#xff0c;正為這一愿景的實現提供強大助力。從技術原理角度深入剖析&#xff0c;鴻蒙系統究竟如何支撐人工智能在智慧出行場景中的應用呢&#xff1f;這背…

MyBatis-Plus緩存機制深度解析與SpringBoot整合實戰

一、MyBatis-Plus緩存機制全景解析 MyBatis-Plus在MyBatis原生緩存基礎上進行了深度增強,形成了多層次的緩存體系: 1. 緩存層級架構 應用層 ├── MP擴展緩存(多租戶/邏輯刪除) ├── 二級緩存(Mapper級別,跨Session共享) └── 一級緩存(SqlSession級別,默認開…

Day38 | 1365. 有多少小于當前數字的數字、941. 有效的山脈數組、1207. 獨一無二的出現次數、283. 移動零、189. 輪轉數組

1365. 有多少小于當前數字的數字 題目鏈接&#xff1a;1365. 有多少小、于當前數字的數字 - 力扣&#xff08;LeetCode&#xff09; 題目難度&#xff1a;簡單 代碼&#xff1a; class Solution {public int[] smallerNumbersThanCurrent(int[] nums) {Map<Integer,Inte…

數據人的進階之路:四年數倉實踐與成長思考

前言 在數據倉庫開發的過程中&#xff0c;常常會遇到很多值得思考的問題&#xff0c;它們不僅關乎技術的深度&#xff0c;也涉及業務理解、個人的成長&#xff0c;甚至是數據行業未來的價值。回顧過去的經歷&#xff0c;有很多問題反復出現&#xff0c;甚至成為繞不開的課題&am…

大文件分片上傳及斷點續傳實現

使用 支持分片上傳及斷點續傳 前端使用 vue 2 后端使用 springboot 源碼在私信

圖解AUTOSAR_SWS_IOHardwareAbstraction

AUTOSAR IO硬件抽象層詳解 基于AUTOSAR標準的IO硬件抽象層設計與實現指南 目錄 1. 概述2. 架構設計 2.1 模塊架構概覽2.2 內部組件結構2.3 與其他模塊的交互接口 3. 狀態機 3.1 狀態定義3.2 狀態轉換3.3 狀態行為 4. ADC信號處理流程 4.1 初始化流程4.2 轉換請求和處理4.3 通知…

Python正則表達式(一)

目錄 一、正則表達式的基本概念 1、基本概念 2、正則表達式的特殊字符 二、范圍符號和量詞 1、范圍符號 2、匹配漢字 3、量詞 三、正則表達式函數 1、使用正則表達式&#xff1a; 2、re.match()函數 3、re.search()函數 4、findall()函數 5、re.finditer()函數 6…

北京交通大學第三屆C語言積分賽

作者有言在先&#xff1a; 題解的作用是交流思路&#xff0c;不是抄作業的。可以把重點放在思路分析上而不是代碼上&#xff0c;畢竟每個人的代碼風格是不一樣的&#xff0c;看別人的代碼就跟做程序填空題一樣。先看明白思路再看代碼。 還有就是&#xff0c;deepseek真的很好用…

機器學習之條件概率

1. 引言 概率模型在機器學習中廣泛應用于數據分析、模式識別和推理任務。本文將調研幾種重要的概率模型,包括EM算法、MCMC、樸素貝葉斯、貝葉斯網絡、概率圖模型(CRF、HMM)以及最大熵模型,介紹其基本原理、算法流程、應用場景及優勢。 2. EM算法(Expectation-Maximizati…

硬件基礎--03_電流

電流 十九世紀初:[電流方向]是指正電荷的移動方向。 后來:對于金屬導體&#xff0c;正電荷沒移動&#xff0c;其實是電子在移動。 為了定義的統一性[電流方向]仍然定義為正電荷的移動方向 所以:[電流方向]與[電子移動方向]是相反的。 概念:電荷的定向移動&#xff0c;形成了電…

multi paxos協議

1. Redo Log 同步的核心目標 ?數據一致性&#xff1a;確保所有副本在事務提交后具有相同的數據視圖。?容錯性&#xff1a;在主副本故障時&#xff0c;從副本能快速接管并恢復數據。?高吞吐&#xff1a;通過批量同步和并行處理提升效率。 2. Multi Paxos 協議的同步流程 M…

借壹起航東風,中國工廠出海開啟新征程

在經濟全球化不斷深入的當下&#xff0c;中國工廠正以積極的姿態投身海外市場&#xff0c;渴望在全球商業版圖中占據一席之地&#xff0c;綻放獨特的光彩。然而&#xff0c;出海之路充滿了挑戰與艱辛&#xff0c;品牌塑造困難重重、詢盤量不穩定、營銷成本居高不下等問題&#…

【MySQL】監控MySQL

目錄 使用狀態變量監控MySQL 使用性能模式&#xff08;Performance Schema&#xff09;監控MySQL 1.性能模式 2.性能模式設置表 3.sys模式 使用狀態變量監控MySQL 使用 show status 語句評估系統運行狀況。 可以添加范圍修飾符global或session來顯示全局或本地狀態信息。…

在linux系統上卸載并重新安裝Docker及配置國內鏡像源指

前言 Docker 作為容器化技術的核心工具&#xff0c;廣泛應用于開發、測試和部署環境。但在某些情況下&#xff08;如版本沖突、配置錯誤等&#xff09;&#xff0c;可能需要徹底卸載并重新安裝 Docker。此外&#xff0c;國內用戶直接訪問 Docker 官方鏡像源可能速度較慢&#…

Mysql內置函數篇

&#x1f3dd;?專欄&#xff1a;Mysql_貓咪-9527的博客-CSDN博客 &#x1f305;主頁&#xff1a;貓咪-9527-CSDN博客 “欲窮千里目&#xff0c;更上一層樓。會當凌絕頂&#xff0c;一覽眾山小。” 目錄 7.函數 7.1 日期函數 函數總&#xff1a;?編輯 獲得當前日期 獲得…