What is the relationship between hook_cron() and hook_cron_queue_info()? Some modules (e.g. Feeds, Rules Scheduler, Revision Scheduler) implement both hook_cron() and hook_cron_queue_info(). When used with Ultimate Cron and the Enable cron queue processing setting enabled, this causes two jobs to appear in the jobs list. Are both jobs necessary?

Taking the Revision Scheduler module as an example, its hook_cron() seems to add items to the queue:

function revision_scheduler_cron() {
  $ids = db_query("SELECT * FROM {revision_scheduler} WHERE time_scheduled &lt;= :now AND time_queued = 0 AND time_executed = 0 ORDER BY id ASC", array(':now' =&gt; REQUEST_TIME))-&gt;fetchCol();
  if ($operations = revision_scheduler_operation_load_multiple($ids)) {
    $queue = DrupalQueue::get('revision_scheduler');
    foreach ($operations as $operation) {
      if ($queue-&gt;createItem($operation)) {
        db_update('revision_scheduler')
          -&gt;fields(array('time_queued' =&gt; REQUEST_TIME))
          -&gt;condition('id', $operation-&gt;id)
          -&gt;execute();
      }
    }
  }
}


whereas its hook_cron_queue_info() function calls a function that processes single revision operations:

function revision_scheduler_cron_queue_info() {
  $info['revision_scheduler'] = array(
    'worker callback' =&gt; 'revision_scheduler_operation_process',
    'time' =&gt; variable_get('revision_scheduler_cron_time', 30),
  );
  return $info;
}


Is it the case that hook_cron() adds the items to the queue and hook_cron_queue_info() processes them? 

The documentation for hook_cron_info() says this:


  While there can be only one hook_cron() process running at the same
  time, there can be any number of processes defined here running.
  Because of this, long running tasks are much better suited for this
  API. Items queued in hook_cron() might be processed in the same cron
  run if there are not many items in the queue, otherwise it might take
  several requests, which can be run in parallel.


I'm not sure how to interpret that, but it seems to suggest tasks should be processed with one or the other.
The relationship is they are 2 independent hooks that can be used in conjunction with one another depending on what the task is. 


hook_cron(): Provides a means to supply a custom function to respond to a cron event.
hook_cron_queue_info(): Provide a means to supply queue metadata for a cron event that will need a queue (i.e. any task that can't be fully processed in the limited time during a cron event).


In your example above:


Yes revision_scheduler_cron is adding to the queue. 
But no, revision_scheduler_cron_queue_info is not processing the queue, it's providing the function (revision_scheduler_operation_process) to call for processing and how long (revision_scheduler_cron_time) it should be allowed to execute for processing.