1

I am trying to write a small program that runs on a loop and executes some code every 30 seconds.

I don't care very much about it being exact on the timing, but I do care that the program can compile & run on a linux platform, and that it can be built & tested using the swift package manager.

My first shot was like

while true {
    print("doing the work")
    sleep(30) // also tried usleep(30*1000*1000)
}

Apparently there is no reference to sleep(_:) in swift 4 that I can find, and that code does not compile. I have tried to use a Timer, but the program exits as soon as the timer starts ticking because the timer runs in the background and the main thread's only job is to schedule it.

This has to be easier than it seems. What am I missing about thread management in Swift that would explain how hard I find this?

--- EDIT To clarify why this is different from numerous suggested duplicates:

I am explicitly trying to sleep the main thread, and as I mentioned above, I had been unable to get Swift on Linux to compile using the sleep function suggested by the accepted answers elsewhere. The context of my program in a CLI context means that delayed actions in background thread, as suggested by numerous other sources available, will not work here. Additionally, this CLI is running on Linux, and so I can't depend on iOS-only libraries.

qqq
  • 1,360
  • 1
  • 9
  • 24
  • 1
    Is the `Thread` class from the `Foundation` framework available on Linux? – rmaddy Jun 27 '18 at 03:00
  • 1
    `sleep` and `usleep` should be available from Glibc. `import Glibc`. Although for almost all use cases, you should run from `sleep` as fast as you can. `Foundation.Timer` or `Dispatch.DispatchSourceTimer` are almost always preferable. – Alexander Jun 27 '18 at 03:08
  • Possible duplicate of [How to create a delay in Swift?](https://stackoverflow.com/q/27517632/608639), [How to sleep for few milliseconds in swift?](https://stackoverflow.com/q/38119742/608639), [How to program a delay in Swift](https://stackoverflow.com/q/38031137/608639), [How to make thread sleep for seconds in iOS?](https://stackoverflow.com/q/28896008/608639), [Sleep or delay a Timer thread in Swift](https://stackoverflow.com/q/42742608/608639), etc. – jww Jun 27 '18 at 06:41
  • I have looked through all those questions, but the questions and additionally the answers presume an iOS context where sleeping a main thread is very undesirable, and in my case that is precisely what I want; and additionally the invocations as I describe are not available in Linux. That being said, @Alexander is quite right -- the problem I had is that Glibc and Darwin packages have to be selectively imported based on compile platform. – qqq Jun 28 '18 at 01:47
  • @Quintana What's the problem with selectively importing Glibc or Darwin? – Alexander Jun 28 '18 at 06:11
  • @Alexander no problem with that, i don't think i can accept it as the answer though if it's a comment, is that correct? – qqq Jun 30 '18 at 03:34

2 Answers2

5

You can import sleep from Glibc or Darwin, but better yet, you can use Thread.sleep(forTimeInterval:) from Foundation

import Foundation

while true {
    print("hello")
    Thread.sleep(forTimeInterval: 0.1)
}
Alexander
  • 59,041
  • 12
  • 98
  • 151
1

Try this one

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(30), execute: {
    // Put your code which should be executed with a delay here
})