CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2005
    Posts
    1,030

    An interesting multithreading question

    Supposedly we have a method which accepts an integer as an argument and print on console. This method is accessed by multiple threads. If two or more threads call the method with same value then only one thread should allow to print the value other threads should wait. If values are different then all threads should allow to print the value.
    Basically here I don't know how to tell if multiple threads call the method with different values? Any multithreading guru here gives me an idea? Thanks.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: An interesting multithreading question

    One way is to create a thread safe dictionary of indexed lock objects. The key would be the integer value and the dictionary value would be the lock object.

    You would lock the dictionary and check if it has the integer key.

    If it doesn't have the integer key, you create a new lock object and add it to the dictionary and lock the new lock object.

    Next you unlock the list, when the work is done for that integer you unlock that work object.

    For the case where the dictionary has the integer key, you wait on the lock object.

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: An interesting multithreading question

    What is the reason of such a strange design?
    Victor Nijegorodov

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: An interesting multithreading question

    If two or more threads call the method with same value then only one thread should allow to print the value other threads should wait.
    Wait for what and then do what?

    Are you saying that only unique values from any thread should be displayed on the console? Is there a specific valid range of these integer values or can they be in the full int limit?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Jul 2005
    Posts
    1,030

    Re: An interesting multithreading question

    Quote Originally Posted by Arjay View Post
    One way is to create a thread safe dictionary of indexed lock objects. The key would be the integer value and the dictionary value would be the lock object.

    You would lock the dictionary and check if it has the integer key.

    If it doesn't have the integer key, you create a new lock object and add it to the dictionary and lock the new lock object.

    Next you unlock the list, when the work is done for that integer you unlock that work object.

    For the case where the dictionary has the integer key, you wait on the lock object.
    I am not sure if I understand your idea correctly. Suppose we have three threads A, B and C. When thread A that will pass value 16 to the function tries to access the dictionary, since the dictionary is empty, so a new lock object is created. But then when thread B that will pass value 17 to the function tries to access the dictionary, since the dictionary has the key, so the thread B will have to wait on the lock object? Obviously it doesn't satisfy the requirement of the question. Thanks.

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: An interesting multithreading question

    You don't say whether you are using c++11 or not. I'm still not really sure totally what you mean in your post #1. However if you have multiple threads that generate a number and you only want unique numbers to be displayed on the console, then consider this test example. display() is the function that displays these unique numbers. It basically uses an unordered set to hold those numbers which have already been displayed which is protected by a mutex lock guard.

    Code:
    #include <iostream>
    #include <iomanip>
    #include <unordered_set>
    #include <thread>
    #include <mutex>
    #include <vector>
    using namespace std;
    
    const int numThreads = 5;
    const int maxnum = 2000;
    
    void display(int num)
    {
    static mutex m;
    static unordered_set<int> us;
    
    lock_guard<mutex> lock(m);
    	
    	if ((us.insert(num)).second == true)
    		cout << setw(7) << num << " ";
    }
    
    void upnums()
    {
    	for (int num = 0; num <= maxnum; ++num) {
    		this_thread::yield();
    		display(num);
    	}
    }
    
    void downnums()
    {
    	for (int num = maxnum; num >= 0; --num) {
    		this_thread::yield();
    		display(num);
    	}
    }
    
    int main()
    {
    vector<thread> threads;
    
    	for (int i = 0; i < numThreads; i += 2) {
    		threads.push_back(thread(downnums));
    		threads.push_back(thread(upnums));
    	}
    
    	for (auto& th : threads) th.join();
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: An interesting multithreading question

    Quote Originally Posted by LarryChen View Post
    I am not sure if I understand your idea correctly. Suppose we have three threads A, B and C. When thread A that will pass value 16 to the function tries to access the dictionary, since the dictionary is empty, so a new lock object is created. But then when thread B that will pass value 17 to the function tries to access the dictionary, since the dictionary has the key, so the thread B will have to wait on the lock object? Obviously it doesn't satisfy the requirement of the question. Thanks.
    Yes, you misunderstand. The one lock for the dictionary is different than the 'value' locks. The dictionary lock is to make the dictionary thread safe (and all access goes through this lock). However, because dictionary access is fast, this lock is only ever held for a very short time.

    From there, the code either acquires a 'value' lock or waits on the 'value' lock. To see this working, simulate some real work for each thread (rather than simply displaying a value in the console) by adding some sleep to the console write operation.

  8. #8
    Join Date
    Jul 2013
    Posts
    576

    Re: An interesting multithreading question

    Quote Originally Posted by LarryChen View Post
    I don't know how to tell if multiple threads call the method with different values?
    I would use a thread-safe producer-consumer queue. The producer threads push integers on the queue at any time. The consumer thread pops the integers one by one as they arrive and prints them on the console according to the no-doubles rule.

    I interpret the no-doubles rule to mean that if the same integer arrives within a certain time-interval it should be printed once only. To implement this rule the consumer thread maintains a secondary data structure (SDS) which holds integers marked with time-stamps.

    When the consumer thread pops an integer for printing it also takes a current time-stamp (CTS). First all integers in the SDS that are more than one time-interval older than the CTS are removed. Then if the integer is not in the SDS it's added to the SDS, marked with the CTS, and printed. If the integer is in the SDS already it's discarded because it's a double. (Or, as an alternative, if the integer is in the SDS already it's discarded but the integer in the SDS is updated with the CTS. In this way the time-interval will be restarted if a double arrives.)
    Last edited by razzle; April 26th, 2015 at 06:58 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured