📄 gthreadpool.c
字号:
* to do. **/void g_thread_pool_push (GThreadPool *pool, gpointer data, GError **error){ GRealThreadPool *real = (GRealThreadPool*) pool; g_return_if_fail (real); g_async_queue_lock (real->queue); if (!real->running) { g_async_queue_unlock (real->queue); g_return_if_fail (real->running); } if (g_async_queue_length_unlocked (real->queue) >= 0) /* No thread is waiting in the queue */ g_thread_pool_start_thread (real, error); g_async_queue_push_unlocked (real->queue, data); g_async_queue_unlock (real->queue);}/** * g_thread_pool_set_max_threads: * @pool: a #GThreadPool * @max_threads: a new maximal number of threads for @pool * @error: return location for error * * Sets the maximal allowed number of threads for @pool. A value of -1 * means, that the maximal number of threads is unlimited. * * Setting @max_threads to 0 means stopping all work for @pool. It is * effectively frozen until @max_threads is set to a non-zero value * again. * * A thread is never terminated while calling @func, as supplied by * g_thread_pool_new (). Instead the maximal number of threads only * has effect for the allocation of new threads in g_thread_pool_push(). * A new thread is allocated, whenever the number of currently * running threads in @pool is smaller than the maximal number. * * @error can be %NULL to ignore errors, or non-%NULL to report * errors. An error can only occur when a new thread couldn't be * created. **/voidg_thread_pool_set_max_threads (GThreadPool *pool, gint max_threads, GError **error){ GRealThreadPool *real = (GRealThreadPool*) pool; gint to_start; g_return_if_fail (real); g_return_if_fail (real->running); g_return_if_fail (!real->pool.exclusive || max_threads != -1); g_return_if_fail (max_threads >= -1); g_async_queue_lock (real->queue); real->max_threads = max_threads; if (pool->exclusive) to_start = real->max_threads - real->num_threads; else to_start = g_async_queue_length_unlocked (real->queue); for ( ; to_start > 0; to_start--) { GError *local_error = NULL; g_thread_pool_start_thread (real, &local_error); if (local_error) { g_propagate_error (error, local_error); break; } } g_async_queue_unlock (real->queue);}/** * g_thread_pool_get_max_threads: * @pool: a #GThreadPool * * Returns the maximal number of threads for @pool. * * Return value: the maximal number of threads **/gintg_thread_pool_get_max_threads (GThreadPool *pool){ GRealThreadPool *real = (GRealThreadPool*) pool; gint retval; g_return_val_if_fail (real, 0); g_return_val_if_fail (real->running, 0); g_async_queue_lock (real->queue); retval = real->max_threads; g_async_queue_unlock (real->queue); return retval;}/** * g_thread_pool_get_num_threads: * @pool: a #GThreadPool * * Returns the number of threads currently running in @pool. * * Return value: the number of threads currently running **/guintg_thread_pool_get_num_threads (GThreadPool *pool){ GRealThreadPool *real = (GRealThreadPool*) pool; guint retval; g_return_val_if_fail (real, 0); g_return_val_if_fail (real->running, 0); g_async_queue_lock (real->queue); retval = real->num_threads; g_async_queue_unlock (real->queue); return retval;}/** * g_thread_pool_unprocessed: * @pool: a #GThreadPool * * Returns the number of tasks still unprocessed in @pool. * * Return value: the number of unprocessed tasks **/guintg_thread_pool_unprocessed (GThreadPool *pool){ GRealThreadPool *real = (GRealThreadPool*) pool; gint unprocessed; g_return_val_if_fail (real, 0); g_return_val_if_fail (real->running, 0); unprocessed = g_async_queue_length (real->queue); return MAX (unprocessed, 0);}/** * g_thread_pool_free: * @pool: a #GThreadPool * @immediate: should @pool shut down immediately? * @wait: should the function wait for all tasks to be finished? * * Frees all resources allocated for @pool. * * If @immediate is %TRUE, no new task is processed for * @pool. Otherwise @pool is not freed before the last task is * processed. Note however, that no thread of this pool is * interrupted, while processing a task. Instead at least all still * running threads can finish their tasks before the @pool is freed. * * If @wait is %TRUE, the functions does not return before all tasks * to be processed (dependent on @immediate, whether all or only the * currently running) are ready. Otherwise the function returns immediately. * * After calling this function @pool must not be used anymore. **/voidg_thread_pool_free (GThreadPool *pool, gboolean immediate, gboolean wait){ GRealThreadPool *real = (GRealThreadPool*) pool; g_return_if_fail (real); g_return_if_fail (real->running); /* It there's no thread allowed here, there is not much sense in * not stopping this pool immediately, when it's not empty */ g_return_if_fail (immediate || real->max_threads != 0 || g_async_queue_length (real->queue) == 0); g_async_queue_lock (real->queue); real->running = FALSE; real->immediate = immediate; real->waiting = wait; if (wait) { g_mutex_lock (inform_mutex); while (g_async_queue_length_unlocked (real->queue) != -real->num_threads) { g_async_queue_unlock (real->queue); g_cond_wait (inform_cond, inform_mutex); g_async_queue_lock (real->queue); } g_mutex_unlock (inform_mutex); } if (g_async_queue_length_unlocked (real->queue) == -real->num_threads) { /* No thread is currently doing something (and nothing is left * to process in the queue) */ if (real->num_threads == 0) /* No threads left, we clean up */ { g_async_queue_unlock (real->queue); g_thread_pool_free_internal (real); return; } g_thread_pool_wakeup_and_stop_all (real); } real->waiting = FALSE; /* The last thread should cleanup the pool */ g_async_queue_unlock (real->queue);}static voidg_thread_pool_free_internal (GRealThreadPool* pool){ g_return_if_fail (pool); g_return_if_fail (!pool->running); g_return_if_fail (pool->num_threads == 0); g_async_queue_unref (pool->queue); g_free (pool);}static voidg_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool){ guint i; g_return_if_fail (pool); g_return_if_fail (!pool->running); g_return_if_fail (pool->num_threads != 0); g_return_if_fail (g_async_queue_length_unlocked (pool->queue) == -pool->num_threads); pool->immediate = TRUE; for (i = 0; i < pool->num_threads; i++) g_async_queue_push_unlocked (pool->queue, GUINT_TO_POINTER (1));}/** * g_thread_pool_set_max_unused_threads: * @max_threads: maximal number of unused threads * * Sets the maximal number of unused threads to @max_threads. If * @max_threads is -1, no limit is imposed on the number of unused * threads. **/voidg_thread_pool_set_max_unused_threads (gint max_threads){ g_return_if_fail (max_threads >= -1); G_LOCK (unused_threads); max_unused_threads = max_threads; if (max_unused_threads < unused_threads && max_unused_threads != -1) { guint i; g_async_queue_lock (unused_thread_queue); for (i = unused_threads - max_unused_threads; i > 0; i--) g_async_queue_push_unlocked (unused_thread_queue, stop_this_thread_marker); g_async_queue_unlock (unused_thread_queue); } G_UNLOCK (unused_threads);}/** * g_thread_pool_get_max_unused_threads: * * Returns the maximal allowed number of unused threads. * * Return value: the maximal number of unused threads **/gintg_thread_pool_get_max_unused_threads (void){ gint retval; G_LOCK (unused_threads); retval = max_unused_threads; G_UNLOCK (unused_threads); return retval;}/** * g_thread_pool_get_num_unused_threads: * * Returns the number of currently unused threads. * * Return value: the number of currently unused threads **/guint g_thread_pool_get_num_unused_threads (void){ guint retval; G_LOCK (unused_threads); retval = unused_threads; G_UNLOCK (unused_threads); return retval;}/** * g_thread_pool_stop_unused_threads: * * Stops all currently unused threads. This does not change the * maximal number of unused threads. This function can be used to * regularly stop all unused threads e.g. from g_timeout_add(). **/void g_thread_pool_stop_unused_threads (void){ guint oldval = g_thread_pool_get_max_unused_threads (); g_thread_pool_set_max_unused_threads (0); g_thread_pool_set_max_unused_threads (oldval);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -