(Google interview) has four threads 1, 2, 3, 4 synchronously write data ... C++11 implementation

Source: Internet
Author: User
Tags semaphore

Recently in the study of multi-threading, the topic originates from Mr. Morewindows's "second Kill multithreading First" (http://blog.csdn.net/morewindows/article/details/7392749)

Title Excerpt:

Question Fifth (Google interview questions)

There are four threads of 1, 2, 3, 4. The function of thread 1 is output 1, the function of thread 2 is output 2, etc... There are now four file ABCD. The initial is empty. Now you want four files to appear in the following format:

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 ....

Please design the program.

The code is implemented as follows:
1#include <iostream>2#include <string>3#include <thread>4#include"Semaphore.h"5 6constexpr unsigned max_count =Ten;7constexpr unsigned max_thread =4;8 9Unsigned getNext (unsigned current,BOOLorder) {Ten     if(order) { OneUnsigned next = current +1; A         returnNext% Max_thread;// //Positive Order -}Else { -Unsigned next = current-1; the         returnNext% Max_thread;//reverse Order -     } - } -  + classFile - { +  Public: AFile (ConstSTD::string& name ="0")  at : M_name (name) -, M_buffer (Max_count,'0') -, M_pos (0){ -          -     } -  in     voidWriteCharc) { -m_buffer.at (m_pos++) =C; to     } +  -STD::stringGetName ()Const { the         returnM_name; *     } $STD::stringGetData ()Const {Panax Notoginseng         returnM_buffer; -     } the Private: +STD::stringM_name; ASTD::stringM_buffer; the size_t M_pos; + }; -  $Semaphore T1 (1), T2 (1), T3 (1), T4 (1); $semaphore* Semaphorearray[max_thread] = {&t1, &t2, &AMP;T3, &T4}; -File Files[max_thread] = {file ("A"), File ("B"), File ("C"), File ("D") }; -unsigned Currentfile[max_thread] = {0,1,2,3};//the file ID that each thread should currently write to the  - voidwrite (unsigned threadId) {Wuyi     Const Charc ='1'+threadId; theauto& FID =Currentfile[threadid]; -     //Auto FID = threadId; WuAuto Nextthreadid = GetNext (ThreadId,true);//Positive Order -unsigned count =0; About      while(Max_count! =count) { $Semaphorearray[threadid]->wait (); -         //Write a file - Files[fid].write (c); -         //Pass the file to the next thread.  ASemaphorearray[nextthreadid]->signal (); +         //update the file ID to be written theFID = GetNext (FID,false);//Reverse -++count; $     } the } the  the  the intMain () { -Std::cout <<"Hello"<<Std::endl; in  the     //Create thread the Std::thread Threads[max_thread]; About      for(Unsigned i =0; I! = Max_thread; ++i) { theThreads[i] =Std::thread (write, i); the     } the  +     //Join -      for(auto&thread:threads) { the Thread.Join ();Bayi     } the  the     //Output -      for(Constauto&file:files) { -Std::cout << file.getname () <<": "<< File.getdata () <<Std::endl; the     } the  theStd::cout <<"Bye"<<Std::endl; the     return 0; -}

Where Semaphore.h's code is shown in: http://www.cnblogs.com/waterfall/p/7966116.html

Operation Result:

Code parsing:

First of all, this code with the file class simulation files written to facilitate print debugging. The Void File::write (char c) method appends the character C to the end of the file.

As you can see from the topic, when a file (such as file a) is written by thread 1, it needs to be written by the next thread, thread 2.  So there will be a:1 2 3 4 1 ... The B,c,d file is the same, except that the initial write thread is different.

In the Code type utilization:

0 1 2 3 // the file ID that each thread should currently write to

Specifies which file each thread writes to initially. If you do not want to configure, you can also use ThreadID as the file ID of the thread's initial write (the one commented out in the Write function), they are just equal.

The number of times the thread can write writes is represented in the code with semaphores. The Write function automatically calculates the next file to be written after a file is written. Order for a,d,c,b,a ...., reverse.

Semaphore T1 (1), T2 (1), T3 (1), T4 (1);//For setting the semaphore Semaphore* Semaphorearray[max_thread] = {&t1, &t2, &t3, &T4}; Putting an array is just for the convenience of calling

If you just set the semaphore for thread 1 to 1, the others are set to 0. The health of a thread can be seen as:

Step1: Thread 1 semaphore 1 a->d thread 2 semaphore 0 B blocking thread 3 semaphore 0 C blocking thread 4 semaphore 0 D blocking

Step2: Thread 1 semaphore 0 D block thread 2 semaphore 1 b->a thread 3 semaphore 0 C block thread 4 Semaphore 0 D block

Step3: Thread 1 semaphore 0 D blocking thread 2 semaphore 0 A blocking thread 3 semaphore 1 c->b thread 4 semaphore 0 D block

STEP4: Thread 1 semaphore 0 D blocking thread 2 semaphore 0 A blocking thread 3 semaphore 0 B blocking thread 4 semaphore 1 d->c

The first run ends: Thread 1 writes 1 in file A, thread 2 writes 2 in file B, thread 3 writes 3 in file C, and thread 4 writes 4 in file D.

Then the second round begins: Thread 1 writes 1 in file D, thread 2 writes 2 in file a ...

And so on, the equivalent of only 1 threads at the same time are working. Each time the thread is working, the character is written to the file that it is currently writing to, and the next file to be written is computed.

There is clearly no conflict in this situation.

If you set the initial semaphore of thread 1 to 2:

Step1: Thread 1 semaphore 2 a->d thread 2 semaphore 0 B blocking thread 3 semaphore 0 C blocking thread 4 semaphore 0 D blocking

Step2: Thread 1 semaphore 1 d->c thread 1 semaphore 1 b->a thread 3 semaphore 0 C block thread 4 Semaphore 0 D block

You can see that the character 1 is written in file D and an error occurs. The reason is that file D is currently expecting to be written by thread 4 and is not ready before 4 writes. It is wrong to write to any other thread at this time.

If the initial semaphore of thread 1 and thread 4 is assumed to be 1, the other is 0. and assume that thread 4 runs first

step1.1: Thread 1 semaphore 1 A ready thread 2 semaphore 0 B blocking thread 3 semaphore 0 C blocking thread 4 semaphore 1 d->c

step1.2: Thread 1 semaphore 2 a->d thread 2 semaphore 0 B blocking thread 3 semaphore 0 C blocking thread 4 semaphore 0 C blocking

step2.1: Thread 1 semaphore 1 d->c thread 1 semaphore 1 b->a thread 3 semaphore 0 C block thread 4 Semaphore 0 D block

File d is first written to the character 4 by thread 4, followed by thread 1 to write character 1 to meet the requirements. (The sequence of D should be: 4 1 2 3 4 ...)

That is, the increase in the semaphore of thread 1 is based on the previous thread having finished writing the file. At this point the file is in a ready state and can be used by the next thread to pass the file to the next thread.

So in the final code, set the initial semaphore for each thread to 1. To meet the requirements of the topic. Even if any thread is blocked in execution (sleep emulation is available), it does not affect other threads running.

Suppose a long sleep is performed in thread 1. The possible operating conditions are as follows

STEP0: Thread 1 semaphore 1 A Ready thread 2 semaphore 1 B ready thread 3 semaphore 1 C Ready thread 4 semaphore 1 D ready

After some time ...

Step1: Thread 1 semaphore 4 a Ready thread 2 semaphore 0 A blocking thread 3 semaphore 0 A blocking thread 4 semaphore 0 A blocking

All threads are waiting for the data to be written to file a. However, only thread 1 writes the character 1 in file A before releasing the signal, B to continue writing. And then the c,d. There is still no conflict. File A also satisfies the 1,2,3,4 character order.

Other:

Many of the online search code, at the same time only allow one thread to write the file, or through the count, the end of the round before the next write. This code really implements the parallelism between threads. Wait only if there is no file to write.

Thank you.

(Google interview) has four threads 1, 2, 3, 4 synchronously write data ... C++11 implementation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.