Swift3 About DispatchSemaphore timeout

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()

----------

Accepted Reply

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?

Replies

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?

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(***) {

~~~

queue.addOperation({ () -> Void in

while (true == control_flag) {

semaphore.wait()

~~~ process ~~~

semaphore.signal()

DispatchQueue.main.async {

txt_Status.text = "sample"

}

}

}

}

-----------

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"

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.

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.

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.

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.

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)

}

}

Just reading your explanation and code snippet, I do not think using semaphore would be the best solution for your issue.


If your two Commuication processing cannot overlap, why don't you just disable two buttons while Commuication processing is going on?

I want to prevent duplication of communication commands.

If they overlap, they get crowded and affect the acquisition of status.

Therefore, I want to incorporate exclusive control.

With disabling two buttons, you can prevent duplication of communication commands.


I do not understand why you insist on using semaphore.