简体   繁体   中英

Can I “force” thread to wake up?

I want to implement a fast logger, that holds log entries, and when a certain trigger arrives, it flushes the last X messages.

So the idea is to hold all the messages in a cyclic buffer, and once we have the trigger, to push it's ID to a queue, which another thread monitors(one thread in all the system). this thread will go back X messages and to flush them. I know how to deal with messages that are being written while I am trying to flush, messages that have been overwritten before I flushed messages that being flushed while I am trying to update them etc.

My problem is, if for example I have 20 threads writing messages, and only 10 cores, in the time deference between 2 "writer" thread's execution, all the buffer will be overwritten several times.

Is there any way that "my" thread can "force" the "writer" thread to execute(or to give it it's time slice? I guess no but still... can you advice on any other way/design to overcome this problem.

As I understand you want to resume your thread as soon as there are new ID's in the queue available. It's possible with locking primitives — your writer thread should sleep until notified from your trigger thread. How to achieve this behavior depends on multithreading framework you are using.

For example, in C++11 you can have a look at std::condition_variable .

Edit. As mentioned in the comments, the disk IO is slow, so you need to fetch the messages to memory in the writer thread, and only then write them to disk. During IO the buffer can be overwritten by the arriving messages.

I've written something similar before, where calls to log methods are actually placed on a queue which another thread ( T-Logger ) monitors. This frees up the other threads from having to having to call the underlying log APIs and works well in low latency applications.

If you want to explicitly buffer and then write on a trigger then I'd still recommend doing all the writes from one thread, such as T-Logger and then use some sort of conditional variable to signal to T-Logger that it should now go and write the items in the queue to the underlying log file.

As mentioned in the question comments, you should avoid having multiple threads trying to do IO. IO is incredible slow, and having all your threads trying to write to a file will cause them to give up their CPU cycles waiting for the IO to complete.

Sounds like a classic case to use a semaphore, initialized with the length of the circular buffer. The log call from the threads needing to log stuff has to get a unit from the semaphore before proceeding and the logging thread signals the semaphore when it extracts an entry from the queue. If the buffer runs out, any thread trying to log will then block until there is space for its log entry.

Obviously, the circular buffer/queue/whatever container for the log entries must be thread-safe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM