Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Thread Safe Linked List

Thread Safe Linked List

Scheduled Pinned Locked Moved C / C++ / MFC
questiondata-structuresperformance
9 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    User 33952
    wrote on last edited by
    #1

    I have a Linked list with the following functions: Add, Get, Delete. For thread safe implementation I use a CRITICAL_SECTION handle in each function and everything work well. The question is: How I can avoid use of CRITICAL_SECTION on Get function? Because Get function is called on many threads the performance is low, each thread wait the previous thread to finish Get. Add and Delete are called rarely. Thanks!

    A J 2 Replies Last reply
    0
    • U User 33952

      I have a Linked list with the following functions: Add, Get, Delete. For thread safe implementation I use a CRITICAL_SECTION handle in each function and everything work well. The question is: How I can avoid use of CRITICAL_SECTION on Get function? Because Get function is called on many threads the performance is low, each thread wait the previous thread to finish Get. Add and Delete are called rarely. Thanks!

      A Offline
      A Offline
      Alexander M
      wrote on last edited by
      #2

      yes you can :) I've already thought about this problem, too, and I found a very fast solution. Lock the list by using interlocked functions, which use a LONG member variable of the class (I assume you use a list class) to synchronize access. Don't try it, just do it! ;-)

      L 1 Reply Last reply
      0
      • U User 33952

        I have a Linked list with the following functions: Add, Get, Delete. For thread safe implementation I use a CRITICAL_SECTION handle in each function and everything work well. The question is: How I can avoid use of CRITICAL_SECTION on Get function? Because Get function is called on many threads the performance is low, each thread wait the previous thread to finish Get. Add and Delete are called rarely. Thanks!

        J Offline
        J Offline
        Joaquin M Lopez Munoz
        wrote on last edited by
        #3

        You can safely eliminate the CRITICAL_SECTION in your Get function if you make sure that your program is playing by the rules: as many threads can have read-only access to the list as long as none of them does an insertion or deletion. This usually involves some other synchronization mechanisms, although at a higher level than on the linked list itself, which presumably will yield better performance. If you cannot guarantee this behavior in your program, another possibility is to protect access by means of a read/write lock. Such a lock allows multiple threads to enter for read access, except if some thread has reclaimed write access. A web search gives the following article[^] by Ivan Krivyakov on implementing read/write locks in Windows. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

        L 1 Reply Last reply
        0
        • J Joaquin M Lopez Munoz

          You can safely eliminate the CRITICAL_SECTION in your Get function if you make sure that your program is playing by the rules: as many threads can have read-only access to the list as long as none of them does an insertion or deletion. This usually involves some other synchronization mechanisms, although at a higher level than on the linked list itself, which presumably will yield better performance. If you cannot guarantee this behavior in your program, another possibility is to protect access by means of a read/write lock. Such a lock allows multiple threads to enter for read access, except if some thread has reclaimed write access. A web search gives the following article[^] by Ivan Krivyakov on implementing read/write locks in Windows. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

          L Offline
          L Offline
          Laing James
          wrote on last edited by
          #4

          Hi. A fast way to ensure synchronised access and update, is to use a simple 'mutex' that all three access/update methods conform to, ( as long as it is not a multi processor platform ). If you do not care about the specific order in which access and/or update is performed, ie) its a free for all, then a simple WaitForSingleObject() on the mutex should provide a simple and fast mechanism. James.

          J 1 Reply Last reply
          0
          • L Laing James

            Hi. A fast way to ensure synchronised access and update, is to use a simple 'mutex' that all three access/update methods conform to, ( as long as it is not a multi processor platform ). If you do not care about the specific order in which access and/or update is performed, ie) its a free for all, then a simple WaitForSingleObject() on the mutex should provide a simple and fast mechanism. James.

            J Offline
            J Offline
            Joaquin M Lopez Munoz
            wrote on last edited by
            #5

            I'm afraid I'm not getting your point. If you protect every function of the list (Get, Add and Delete), with a mutex, you'll get esentially what the original poster has already done with a CRITICAL_SECTION, with the added penalty that mutexes are heavier. My hunch is that the original poster asks for a way to allow many concurrent threads to be granted read access at a time, and not in a strictly one-by-one basis. Do you think this can be done with mutexes? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

            L 1 Reply Last reply
            0
            • J Joaquin M Lopez Munoz

              I'm afraid I'm not getting your point. If you protect every function of the list (Get, Add and Delete), with a mutex, you'll get esentially what the original poster has already done with a CRITICAL_SECTION, with the added penalty that mutexes are heavier. My hunch is that the original poster asks for a way to allow many concurrent threads to be granted read access at a time, and not in a strictly one-by-one basis. Do you think this can be done with mutexes? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

              L Offline
              L Offline
              Laing James
              wrote on last edited by
              #6

              Hi. By using a simple mutex, access and update can be synchonised very easily. When the list needs to be updated, the mutex is 'set', the update is performed, this excludes all access's, the update is complete and the mutex is 'released'. Since the majority of the operations, as per the 'poster' are accesses, waiting for the mutex is infrequent. Since for the majority of the time, the mutex is 'released' the wait for reads' is satisfied 'immediately' James.

              J 1 Reply Last reply
              0
              • L Laing James

                Hi. By using a simple mutex, access and update can be synchonised very easily. When the list needs to be updated, the mutex is 'set', the update is performed, this excludes all access's, the update is complete and the mutex is 'released'. Since the majority of the operations, as per the 'poster' are accesses, waiting for the mutex is infrequent. Since for the majority of the time, the mutex is 'released' the wait for reads' is satisfied 'immediately' James.

                J Offline
                J Offline
                Joaquin M Lopez Munoz
                wrote on last edited by
                #7

                I'm still not getting you. AFAIK the only way to set a Win32 mutex is by waiting on it; releasing is done via ReleaseMutex. So your proposal is that the update function properly waits for the mutex and releases it after updating is completed, right? So, what should the access (i.e. read-only) function do?

                • if the access function also waits for the object, then there cannot be more than one thread either updating or reading at a time, exactly the same way as it happens with using a CRITICAL_SECTION.
                • if the access function does not wait for the mutex, the list is not thread safe, as when the update method enters there could be other threads performing read-only acess at that time, and corruption of the data structure can hence ensue.

                Maybe I am not getting your proposal right :confused: Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                L 1 Reply Last reply
                0
                • J Joaquin M Lopez Munoz

                  I'm still not getting you. AFAIK the only way to set a Win32 mutex is by waiting on it; releasing is done via ReleaseMutex. So your proposal is that the update function properly waits for the mutex and releases it after updating is completed, right? So, what should the access (i.e. read-only) function do?

                  • if the access function also waits for the object, then there cannot be more than one thread either updating or reading at a time, exactly the same way as it happens with using a CRITICAL_SECTION.
                  • if the access function does not wait for the mutex, the list is not thread safe, as when the update method enters there could be other threads performing read-only acess at that time, and corruption of the data structure can hence ensue.

                  Maybe I am not getting your proposal right :confused: Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                  L Offline
                  L Offline
                  Laing James
                  wrote on last edited by
                  #8

                  Hi. Sorry, I assumed that there were multiple threads waiting on 'access and/or update', otherwise the question is void. There can be as many threads waiting on the mutex as there is. The idea is that only an update 'locks' the mutex, 'reads', 'fall through'. Otherwise we might be talking about a DOS program. James.

                  1 Reply Last reply
                  0
                  • A Alexander M

                    yes you can :) I've already thought about this problem, too, and I found a very fast solution. Lock the list by using interlocked functions, which use a LONG member variable of the class (I assume you use a list class) to synchronize access. Don't try it, just do it! ;-)

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    I have used 2 interlocked vars and a semaphore. Below is a schematic of the code. In this case the Get Thread has a very high access on the resource at 2 - 3 mil. of gets/sec towards 20 - 50 of add and del /sec If you have a better idea please tell me. Thank you. Get() { InterlockedIncrement(&_read); while(_write > 0) Sleep(0); CList::Get(); InterlockedDecrement(&_read); } Add() { while(_read > 0) Sleep(0); InterlockedIncrement(&_write); WaitForSingleObject(_sem,INFINITE); CList::Add(); ReleaseSemaphore(_sem,1,NULL); InterlockedDecrement(&_write); } Delete() { while(_read > 0) Sleep(0); InterlockedIncrement(&_write); WaitForSingleObject(_sem,INFINITE); CList::Add(); ReleaseSemaphore(_sem,1,NULL); InterlockedDecrement(&_write); }

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups