多线程google面试题

    xiaoxiao2025-01-09  16

    有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推…现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:

    A:1 2 3 4 1 2…

    B:2 3 4 1 2 3…

    C:3 4 1 2 3 4…

    D:4 1 2 3 4 1…

    问题分析:

    由于每个线程都固定输出一个字符,这个是不会发生变化的,要想达到预期效果,只能是每次循环向不同的文件写字符。这里考察的是线程间同步问题,线程1完成后,才会开始线程2,以此类推。

    为了方便分析,我们将题目要求的格式进行转换,给出每次循环每个线程写入的目标文件,格式如下:

    可以分析出,下一轮循环写入的文件有如下格式:

    static char szFileName[4][32] ={ "A.txt", "B.txt", "C.txt", "D.txt" }; NextLoopFile([i+1) % 4] = CurrentFile[i]

    我们利用C++11中提供的条件变量完成完成题目要求:

    具体代码如下:

    #include <thread> #include <fstream> #include <condition_variable> #include <mutex> std::condition_variable g_cvWriter; std::mutex g_mutex_writer; const unsigned MAX_THREAD_NUM = 4; const unsigned MAX_LOOP_NUM = 10; //控制线程执行流程 unsigned g_nNextThreadID = 0; //每一轮的文件ID unsigned g_nCurrentFileIndex[MAX_THREAD_NUM] = { 0, 1, 2, 3}; //文件名 char g_szFileName[MAX_THREAD_NUM][32] = { "A.txt", "B.txt", "C.txt", "D.txt" }; //每个线程输出的字符 char GetChar(unsigned nID) { return nID + '1'; } // 每一轮的文件ID void GetNextLoopFileIndex() { unsigned nNewLoopFileName[MAX_THREAD_NUM] = { 0 }; //C[i] = N[(i+1)%max_num] for (int i = 0; i < MAX_THREAD_NUM; i++) { nNewLoopFileName[(i + 1) % MAX_THREAD_NUM] = g_nCurrentFileIndex[i]; } memcpy(g_nCurrentFileIndex, nNewLoopFileName, sizeof(nNewLoopFileName)); } char* GetFileName(unsigned nID) { return g_szFileName[g_nCurrentFileIndex[nID]]; } void WriterChar2File(const char* szFileName, char ch) { std::fstream file(szFileName, std::ostream::out | std::ostream::app); file << ch; file << std::endl; } //nID从 0 1 2 3 void WriterCharThread(unsigned nID) { for (int i = 0; i < MAX_LOOP_NUM; i++) { std::unique_lock<std::mutex> lk(g_mutex_writer); //线程同步 g_cvWriter.wait(lk, [=](){ return nID == g_nNextThreadID; }); char ch = GetChar(nID); const char* pszFileName = GetFileName(nID); WriterChar2File(pszFileName, ch); g_nNextThreadID++; //新一轮的开始 if (nID + 1 == MAX_THREAD_NUM) { GetNextLoopFileIndex(); g_nNextThreadID = 0; } //唤醒所有被挂起的线程,同时检查是否满足条件 ,满足条件的会继续执行 g_cvWriter.notify_all(); } } void main_thread() { std::thread arrThread[MAX_THREAD_NUM]; for (unsigned i = 0; i < MAX_THREAD_NUM; i++) { arrThread[i] = std::thread(WriterCharThread, i); } for (int i = 0; i < MAX_THREAD_NUM; i++) { arrThread[i].join(); } }

    运行结果:

    最新回复(0)