11 Replies
      Latest reply: Jan 31, 2017 3:29 AM by OOPer RSS
      acopalist Level 1 Level 1 (0 points)

        Please help me.

        I Try exclusive control.

        I want to set a timeout on a semaphore.

        However, I am in trouble because I do not know the proper syntax.

        Perhaps I expect to use "semaphore.wait (timeout: __)", but I cant do it well

         

        ----------

        /* create */

        static var semaphore = DispatchSemaphore(value: 1)

         

        semaphore.wait()

        ~~~Perform communication processing~~~

        semaphore.signal()

        ----------

        • Re: Swift3 About DispatchSemaphore timeout
          OOPer Level 7 Level 7 (3,395 points)

          Please show your code using `semaphore.wait (timeout: __)` with relevant parts. `wait(timeout:)` is the right method, so you need to explain what "I cant do it well" means. Compile-time error? Runtime error? Runs without errors but behaves unexpectedly?

           

          ---

          By the way, generally, you should not call `semaphore.wait()` in the main thread. Are you alright with this?

            • Re: Swift3 About DispatchSemaphore timeout
              acopalist Level 1 Level 1 (0 points)

              Thank you for your reply.

              The problem I mentioned was solved.

              Although it is what you pointed out,

              Does that mean that the main thread should not be stopped?

               

              I will investigate,

              If you have documents to refer to,

              please let me know if you can tell me.

              I appreciate it.

               

              im sorry. I depend on translators.

               

              ----------

              var queue = Operationqueue()

              var semaphore = DispatchSemaphore(value: 1)

               

              @IBAction func xxxxx(xxx) {

                   ~~~

                   queue.addOperation({ () -> Void in

                        while (true == control_flag) {

                             semaphore.wait()

                             ~~~ process ~~~

                             semaphore.signal()

                           

                             DispatchQueue.main.async {

                                  txt_Status.text = "sample"

                             }

                        }

                   }

              }

              -----------

                • Re: Swift3 About DispatchSemaphore timeout
                  eskimo Apple Staff Apple Staff (6,470 points)

                  Does that mean that the main thread should not be stopped?

                  Blocking the main thread causes your app to become unresponsive to UI events.  That’s not good, and if it goes on for too long then your app will be killed by the watchdog.

                  Most folks encounter this in the context of doing network I/O, where things work just fine when the network is good but then fail when they deploy their apps to environments with poor networking.  QA1693 Synchronous Networking On The Main Thread talks more about this.

                  In general you should not block the main thread (in semaphore.wait() or anything else) unless you can guarantee that it unblock promptly.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                • Re: Swift3 About DispatchSemaphore timeout
                  acopalist Level 1 Level 1 (0 points)

                  I would like to see if my semaphore usage is correct.

                  Does this mean "it will timeout if the semaphore is not finished after 100ms"??

                  -----

                  let semaphoreEnum = dispatch.semaphore.wait(timeout: DispatchTime(uptimeNanoseconds: 1000000))     / 100ms timeout?? */

                  switch (semaphoreEnum.hashValue) {

                  case 0:

                       print("success")

                       ~~~~

                       break

                  case 1:

                       print("timedOut")

                       ~~~~

                       break

                  default:

                       break

                  }

                  dispatch.semaphore.signal()

                  -----

                  I thank you in advance.

                    • Re: Swift3 About DispatchSemaphore timeout
                      OOPer Level 7 Level 7 (3,395 points)

                      I would write it as:

                          let timeoutResult = semaphore.wait(timeout: DispatchTime(uptimeNanoseconds: 100_000_000))     /* 100ms timeout?? */
                          switch timeoutResult {
                          case .success:
                              //In this case, you have gotten the right to access the exclusive resource represented by the semaphore
                              print("success")
                              //~~~~
                              //So, when you finished accessing the resource, you need to `signal` that the access right is free for use
                              semaphore.signal()
                          case .timedOut:
                              //In this case, you could not have gotten the right to access the resource
                              print("timedOut")
                              //~~~~
                              //So, you should not signal anything about the resource
                          }
                      
                      

                       

                      When you have gotten the semaphore, you need to `signal` when it is free. When you have not gotten the semaphore, you should not signal the semaphore.

                       

                      And you may have already learnt, such operations need to be done in the background thread.

                        • Re: Swift3 About DispatchSemaphore timeout
                          acopalist Level 1 Level 1 (0 points)

                          Thank you for your response.

                          I'm sorry many times.

                          In the example shown,

                          What happens when there is no vacancy within 100 ms?

                          Is it simply to keep the status quo?

                           

                          The reason for setting timeout,

                          I want to prevent waiting for a signal forever in the back queue.

                            • Re: Swift3 About DispatchSemaphore timeout
                              OOPer Level 7 Level 7 (3,395 points)

                              You'd better show your use case, before discussing detailed behaviour of semaphores. In some cases, "wait forever" may never happen, in some other cases, you may need to program re-try feature. Please show what you really want to do.

                                • Re: Swift3 About DispatchSemaphore timeout
                                  acopalist Level 1 Level 1 (0 points)

                                  When ButtonAction "1" is pressed, one loop occurs.

                                  In that loop, communication processing is performed periodically.

                                  Even when ButtonAction "2" is pressed, communication processing is performed.

                                  The problem is that the timing of the two communications should not overlap.

                                   

                                  Create a new queue and process it.

                                  In order not to stop the main thread.

                                   

                                  @IBAction func Button_Action1(_ sender: Any) {

                                              Dispatch.queue_1.addOperation({ () -> Void in

                                                  while (true == Control_Flag) {

                                                      Dispatch.semaphore.wait()     /* I want timeout */

                                                      /* Communication processing */


                                                      Dispatch.semaphore.signal()

                                                      usleep(50000)

                                                  }

                                              })

                                          }

                                      }

                                   

                                  @IBAction func Button_Action2(_ sender: Any) {

                                          Dispatch.queue_2.addOperation {

                                              Dispatch.semaphore.wait()     /* I want timeout */

                                              /* Commuication processing */

                                   

                                              Dispatch.semaphore.signal()

                                              usleep(50000)

                                          }

                                      }