3

So my aim is to execute a piece of code handled by a thread (let's say thread 1 using POSIX threads) while cancelling a different thread (thread 2) executing it's respective task. Thread 1 is initiated when a particular event occurs (time based event - in my case 60 seconds).

To achieve this, I was using the sleep() function. But I am told by my mentor that it's a bad practice to use sleep in a multithreaded program. I wasn't able to make sense of his reasoning. So hence I decided to escape here.

If my problem seems too vague, mentioning any drawbacks of sleep() would be appreciated.

Bulat
  • 720
  • 7
  • 15
Ayush Das
  • 41
  • 4
  • The good design is to use timers and wait for their results.Sleep will do essentially the same thing but it doesn't look good. ;-) Ok, the real reason is when you wait for your timer you can also wait for other things while sleep only sleeps. – user6556709 Jun 27 '19 at 09:05
  • I like this question, but I would like it better if it was on https://softwareengineering.stackexchange.com/ instead of SO. I don't know how to ask a moderator to move it there. I can vote to move it to any one of five other stackexchange sites, but softwareengineering is not one of the choices. :-( – Solomon Slow Jun 27 '19 at 14:02
  • Sorry, I'm a relatively new user to this platform will be more thoughtful next time. :-) – Ayush Das Jun 28 '19 at 06:42

2 Answers2

2

I am told by my mentor that it's a bad practice to use sleep in a multithreaded program.

I would push back against that blanket statement.

An alternative to using sleep() as a means to make something happen at a certain time is to submit a task to a timer. If you have a thread that does nothing else except sleep() until a certain time and then make some thing happen, then you could use a timer instead. And, if the thread has a loop that makes the thing happen at periodic intervals, then you could use a recurring timer event or, a timer event that re-submits itself.

If you have multiple threads, each of which exists only to make a certain thing happen at a certain time, then you could streamline your program by using a timer object instead. If your program has a GUI, then you're probably using a GUI framework that already has a timer you can use, so having even one "timing" thread probably wastes resources.

But, when you're talking about threads, your are talking about the architecture of your program, and when you're talking about sleep(), you are talking about a low-level implementation detail. I am automatically suspicious of any hard rule of programming that combines ideas from such widely different levels of design.

If I have a good reason for a thread to exist in my program*, then I will not hesitate to write code that creates it, and if I have a good reason for one of my threads to sleep(),** then I will not hesitate to write that call.


* A good reason for a thread to exist would be to manage some stateful "process" that progresses independently of other "processes" that happen inside the program.

** A good reason for a thread to sleep would be if there was some reason why a pause was needed between two steps of a complex "process" that the thread manages.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
1

There are synchronization primitives that allow a thread to wait for another thread (e.g. mutexes, semaphores, condition variables). sleep() will also have your thread wait, but you either sleep for an unnecessary long time (that might not be enough in case the other thread takes longer) or you'd have to check if the other thread is finished anyway (which you'd need to guard with atomic variables or mutexes anyway).

So for thread synchronization, sleep isn't enough and complicates (+slows down) everything.

tstenner
  • 10,080
  • 10
  • 57
  • 92
  • I'm sorry for the unclear nature of the above problem. So the only shared resource that these two threads share is a queue. So, data is accumulated in the queue for 60 seconds. Thread 2 is supposed to enqueue data every second (in an infinite loop) while thread 2 waits for 60 seconds and dequeues all the data accumulated in that time frame. I have used a starting pointer and ending pointer (enqueue and dequeue operations) to make sure that either threads don't interfere each other. So I felt a need for a mutex was unnecessary. Correct me if I'm wrong,thanks for the input by the way – Ayush Das Jun 27 '19 at 09:20
  • 1
    Without a mutex, the compiler sees that thread 1 never writes to the end pointer and might optimize based on that assumption so you need a mutex. Also, thread 2 might get interrupted so it doesn't finish in 60 seconds. – tstenner Jun 27 '19 at 09:23
  • Thanks, I think I have a better understanding of the problem. – Ayush Das Jun 27 '19 at 09:26