c++併発試験問題

12671 ワード

秒殺マルチスレッド第1編マルチスレッド筆記試験の面接問題のまとめ:https://blog.csdn.net/morewindows/article/details/7392749
50個のマルチスレッド面接問題、あなたはいくらできますか?https://blog.csdn.net/cmyperson/article/details/79610870
マルチスレッドの40個の面接問題まとめ(上)https://blog.csdn.net/u012459345/article/details/51179578
Linuxのマルチスレッドのいくつかの面接問題:https://blog.csdn.net/chencheng126/article/details/44587691?utm_source=blogxgwz7
年間に発生した面接問題-40のマルチスレッド問題のまとめ:https://blog.csdn.net/lis_12/article/details/54380521
https://www.cppfans.org/2167.html
https://blog.csdn.net/phiall/article/details/52385165
https://blog.csdn.net/charles_r_chiu/article/details/79975297
1、サブスレッドは10回ループし、次にメインスレッドは100回ループし、次にサブスレッドは10回ループし、次にメインスレッドは100回ループし、このように50回ループし、コードを書き出してみる.
#include
#include
#include
#include
using namespace std;
mutex m;
condition_variable cond;
int flag=10;
void fun(int num){
    for(int i=0;i<50;i++){
        unique_lock lk(m);//A unique lock is an object that manages a mutex object with unique ownership in both states: locked and unlocked.
        while(flag!=num)
            cond.wait(lk);//   wait    lk.unlock()
        for(int j=0;j

2、POSIXマルチスレッドプログラミング技術を熟知していますか?熟知している場合、作成プログラムは以下の機能を完成する:1)int型グローバル変数g_があるFlagの初期値は0です.2)スレッド1を主線称で起動し、「this is thread 1」を印刷し、g_Flagが1に設定されている3)スレッド2をメインワイヤ名で起動し、「this thread 2」を印刷し、g_Flagは2 4に設定)ラインプログラム1はスレッド2が終了してから終了する必要がある5)メインスレッドはg_を検出しているFlagが1から2になったり、2から1になったりしたときに退出します
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include
//#include  
using namespace std;
atomic flag(0);//        g_Flag     
mutex m;
condition_variable cond1;
condition_variable cond2;
condition_variable cond3;
 
void worker1(int f1){//  1  
	unique_locklk(m);
	
	printf("this is thread%d
",f1); flag = 1; cond3.notify_one(); while (flag != 2) cond1.wait(lk); printf("thread1 exit
"); cond3.notify_one(); } void worker2(int f2){// 1 unique_locklk(m); while (1 != flag) cond3.wait(lk); printf("this is thread%d
", f2); printf("thread2 exit
"); flag = 2; cond1.notify_all(); } int main(){ thread one(worker1, 1); thread two(worker2, 2); one.detach(); two.detach(); //pthread_exit(NULL);// unique_locklk(m); cond3.wait(lk); printf("main thread exit
"); return 0; }

3、スレッドの基本概念、スレッドの基本状態と状態の関係?スレッドはCPUが使用する基本ユニットである.スレッドID、プログラムカウンタ、レジスタセット、スタックから構成されます.同じプロセスに属する他のスレッドとコードセグメント、データセグメント、およびオープンファイルや信号などの他のオペレーティングシステムリソースを共有します.スレッドには、新生ステータス、実行可能ステータス、ブロックされたステータス、死亡ステータスの4つのステータスがあります.
4、マルチスレッドにはいくつかの実現方法がありますが、何ですか.(1)Threadクラスを継承(2)Runnableインタフェース再new Thread(YourRunnableOjbect)を実現
5、以下のマルチスレッドはint型変数xの操作に対して、どのいくつかが同期(D)A.x=y;B.x+;C.++x;D.x=1を行う必要がないか.
6、マルチスレッドのスタックとスタックが公有か私有か(C)
    A:   ,    

    B:   ,   

    C:   ,    

    D:   ,   

7、1つのグローバル変数tally、2つのスレッドが同時に実行され(コードセグメントはいずれもThreadProc)、2つのスレッドが終了した後、tallyは値範囲を取る.
int inttally = 0;//glable
    voidThreadProc()

    {

          for(inti = 1;i <= 50;i++)

               tally += 1;

    }
     :[50,100]

8、プログラムを作成し、3つのスレッドを開き、この3つのスレッドのIDはそれぞれA、B、Cであり、各スレッドは自分のIDをスクリーンに10回印刷し、出力結果はABCの順序で表示しなければならない.如:ABCABC....順番に押す.
構想:信号量で各サブスレッド間の反発を行い,3つの信号量A,B,Cを作成する.初期時Aのリソース数は1,B,Cのリソース数は0,Aにアクセスした後Bのリソース数を1,Bにアクセスした後Cのリソース数を1,Cにアクセスした後Aのリソース数を1とする.3つのサブスレッドを作成して、リソースA、B、Cに順次アクセスします.
#include 
#include 
#include 
#include 

using namespace std;

mutex m;
condition_variable cond;
int count = 0;

void func(int num)
{
    for (int i = 0;i < 10;i++)
    {
        unique_lock ulk(m);
        while(count != num)
        {
            cond.wait(ulk);
        }

        char ch = (num  + 'A'); 
        cout << ch << endl;
        count = (count + 1) % 3;

        cond.notify_all();
    }
}

int main()
{
    int i = 0;
    thread thread1(func, 0);
    thread thread2(func, 1);
    thread thread3(func, 2);

    thread1.join();
    thread2.join();
    thread3.join();

    return 0;
}

9、生産者消費者問題:ある生産者は製品を生産している.これらの製品はいくつかの消費者に提供して消費する.生産者と消費者が同時に実行できるように、両者の間に複数のバッファがあるバッファを設置し、生産者はそれを生産した製品を一つのバッファに入れ、消費者はバッファから製品を取り出して消費することができる.すべての生産者と消費者は非同期で動作しますが、消費者が空のバッファに製品を取り出すことを許可しないか、生産者が製品をいっぱい詰めてまだ取り出されていないバッファに製品を投入することを許可しないか、同期を維持する必要があります.
分析:1人の生産者、2人の消費者を仮定し、バッファサイズは4である.第一に、バッファから製品を取り出すことと、バッファへ製品を投入することは、互いに反発して行わなければならない.キーセグメントと反発量で完了できます.第二に、生産者はバッファが空であることを待たなければならない.そうすれば、製品を投入することができ、消費者はバッファが空でないことを待たなければならない.そうすれば、製品を取り出して消費することができる.また、2つの待機プロセスがあるため、2つのイベントまたは信号量で制御する.
//1    2    4   
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
//         
BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hConsole == INVALID_HANDLE_VALUE)
		return FALSE;
	
	return SetConsoleTextAttribute(hConsole, wAttributes);
}
 
const int END_PRODUCE_NUMBER = 8;   //      
const int BUFFER_SIZE = 4;          //     
int g_Buffer[BUFFER_SIZE];          //   
int g_i, g_j;
CRITICAL_SECTION g_cs;              //       
HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;
 
//       
unsigned int __stdcall ProducerThreadFun(PVOID pM)
{
	for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
	{
		//          
		WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);
		//        
		EnterCriticalSection(&g_cs);
		g_Buffer[g_i] = i;
		printf("        %d         %d
", g_i, g_Buffer[g_i]); g_i = (g_i + 1) % BUFFER_SIZE; LeaveCriticalSection(&g_cs); // ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL); } printf(" ,
"); return 0; } // unsigned int __stdcall ConsumerThreadFun(PVOID pM) { while (true) { // WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE); // EnterCriticalSection(&g_cs); SetConsoleColor(FOREGROUND_GREEN); printf(" %d %d %d
", GetCurrentThreadId(), g_j, g_Buffer[g_j]); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); if (g_Buffer[g_j] == END_PRODUCE_NUMBER)// { LeaveCriticalSection(&g_cs); // ( ) ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL); break; } g_j = (g_j + 1) % BUFFER_SIZE; LeaveCriticalSection(&g_cs); Sleep(50); //some other work to do ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL); } SetConsoleColor(FOREGROUND_GREEN); printf(" %d ,
", GetCurrentThreadId()); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); return 0; } int main() { InitializeCriticalSection(&g_cs); // , , . g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL); g_hSemaphoreBufferFull = CreateSemaphore(NULL, 0, 4, NULL); g_i = 0; g_j = 0; memset(g_Buffer, 0, sizeof(g_Buffer)); const int THREADNUM = 3; HANDLE hThread[THREADNUM]; // hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL); // hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL); hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL); WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE); for (int i = 0; i < THREADNUM; i++) CloseHandle(hThread[i]); // CloseHandle(g_hSemaphoreBufferEmpty); CloseHandle(g_hSemaphoreBufferFull); DeleteCriticalSection(&g_cs); return 0; }

10、1人の書き手は多くの読者がいて、複数の読者は同時に書類を読むことができますが、書き手は書類を書くときに読者が書類を読むことを許さず、同じように読者が読むときに書くこともできません.
分析:まず、待機状況に属するものを探します.第一に、書く人は読者がいないまで書類を書くことができない.第二に、すべての読者は書く者が書類を書くのを待ってから書類を読むことができます.「≪待機|Wait|emdw≫」状況を探してから、相互反発してアクセスするリソースがあるかどうかを確認します.書き手が1人しかいないため,読者は共有可能な読み取りファイルであるため,問題に応じて相互反発アクセスのリソースは必要ない.コードは次のとおりです.
#include "stdafx.h"  
#include "stdio.h"  
#include "stdlib.h"  
#include   
#include   
#include   
#include   
#include   
using namespace std;  
  
//         
#include   
#include   
#include   
//           
BOOL SetConsoleColor(WORD wAttributes)  
{  
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  
    if (hConsole == INVALID_HANDLE_VALUE)  
        return FALSE;  
      
    return SetConsoleTextAttribute(hConsole, wAttributes);  
}  
const int READER_NUM = 5;  //      
//        
CRITICAL_SECTION g_cs, g_cs_writer_count;  
HANDLE g_hEventWriter, g_hEventNoReader;  
int g_nReaderCount;  
//        (       )  
void ReaderPrintf(char *pszFormat, ...)  
{  
    va_list   pArgList;  
      
    va_start(pArgList, pszFormat);  
    EnterCriticalSection(&g_cs);  
    vfprintf(stdout, pszFormat, pArgList);  
    LeaveCriticalSection(&g_cs);  
    va_end(pArgList);  
}  
//        
unsigned int __stdcall ReaderThreadFun(PVOID pM)  
{  
    ReaderPrintf("        %d        ...
", GetCurrentThreadId()); // WaitForSingleObject(g_hEventWriter, INFINITE); // EnterCriticalSection(&g_cs_writer_count); g_nReaderCount++; if (g_nReaderCount == 1) ResetEvent(g_hEventNoReader); LeaveCriticalSection(&g_cs_writer_count); // ReaderPrintf(" %d ...
", GetCurrentThreadId()); Sleep(rand() % 100); // , , ReaderPrintf(" %d
", GetCurrentThreadId()); // EnterCriticalSection(&g_cs_writer_count); g_nReaderCount--; if (g_nReaderCount == 0) SetEvent(g_hEventNoReader); LeaveCriticalSection(&g_cs_writer_count); return 0; } // void WriterPrintf(char *pszStr) { EnterCriticalSection(&g_cs); SetConsoleColor(FOREGROUND_GREEN); printf(" %s
", pszStr); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); LeaveCriticalSection(&g_cs); } // unsigned int __stdcall WriterThreadFun(PVOID pM) { WriterPrintf(" ..."); // WaitForSingleObject(g_hEventNoReader, INFINITE); // ResetEvent(g_hEventWriter); // WriterPrintf(" ....."); Sleep(rand() % 100); WriterPrintf(" "); // SetEvent(g_hEventWriter); return 0; } int main() { printf("
"); printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --

"); // InitializeCriticalSection(&g_cs); InitializeCriticalSection(&g_cs_writer_count); // , g_hEventWriter = CreateEvent(NULL, TRUE, TRUE, NULL); g_hEventNoReader = CreateEvent(NULL, FALSE, TRUE, NULL); g_nReaderCount = 0; int i; HANDLE hThread[READER_NUM + 1]; // for (i = 1; i <= 2; i++) hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL); // hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL); Sleep(50); // for ( ; i <= READER_NUM; i++) hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL); WaitForMultipleObjects(READER_NUM + 1, hThread, TRUE, INFINITE); for (i = 0; i < READER_NUM + 1; i++) CloseHandle(hThread[i]); // CloseHandle(g_hEventWriter); CloseHandle(g_hEventNoReader); DeleteCriticalSection(&g_cs); DeleteCriticalSection(&g_cs_writer_count); return 0; }