Mercurial > hg > nginx-site
comparison xml/en/docs/dev/development_guide.xml @ 1983:7660d6390a9d
Added the "Threads" section into the development guide.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 03 May 2017 12:03:10 +0300 |
parents | 28ee7ab54a90 |
children | 98b713b0a9fa |
comparison
equal
deleted
inserted
replaced
1982:28ee7ab54a90 | 1983:7660d6390a9d |
---|---|
2828 and <literal>NGX_RECONFIGURE_SIGNAL</literal> and sent to the nginx master | 2828 and <literal>NGX_RECONFIGURE_SIGNAL</literal> and sent to the nginx master |
2829 process, whose pid is read from nginx pid file. | 2829 process, whose pid is read from nginx pid file. |
2830 </para> | 2830 </para> |
2831 | 2831 |
2832 </section> | 2832 </section> |
2833 | |
2834 <section name="Threads" id="threads"> | |
2835 | |
2836 <para> | |
2837 It is possible to offload tasks that would otherwise block nginx worker process | |
2838 into a separate thread. | |
2839 For example, nginx may be configured to use threads to perform | |
2840 <link doc="../http/ngx_http_core_module.xml" id="aio">file I/O</link>. | |
2841 Another example is using a library that doesn't have asynchronous interface | |
2842 and thus cannot be normally used with nginx. | |
2843 Keep in mind that threads interface is a helper for existing asynchronous | |
2844 approach in processing client connections, and by no means a replacement. | |
2845 </para> | |
2846 | |
2847 <para> | |
2848 To deal with synchronization the following wrappers over pthreads primitives | |
2849 are available: | |
2850 <programlisting> | |
2851 typedef pthread_mutex_t ngx_thread_mutex_t; | |
2852 | |
2853 ngx_int_t ngx_thread_mutex_create(ngx_thread_mutex_t *mtx, ngx_log_t *log); | |
2854 ngx_int_t ngx_thread_mutex_destroy(ngx_thread_mutex_t *mtx, ngx_log_t *log); | |
2855 ngx_int_t ngx_thread_mutex_lock(ngx_thread_mutex_t *mtx, ngx_log_t *log); | |
2856 ngx_int_t ngx_thread_mutex_unlock(ngx_thread_mutex_t *mtx, ngx_log_t *log); | |
2857 | |
2858 typedef pthread_cond_t ngx_thread_cond_t; | |
2859 | |
2860 ngx_int_t ngx_thread_cond_create(ngx_thread_cond_t *cond, ngx_log_t *log); | |
2861 ngx_int_t ngx_thread_cond_destroy(ngx_thread_cond_t *cond, ngx_log_t *log); | |
2862 ngx_int_t ngx_thread_cond_signal(ngx_thread_cond_t *cond, ngx_log_t *log); | |
2863 ngx_int_t ngx_thread_cond_wait(ngx_thread_cond_t *cond, ngx_thread_mutex_t *mtx, | |
2864 ngx_log_t *log); | |
2865 </programlisting> | |
2866 </para> | |
2867 | |
2868 <para> | |
2869 Instead of creating a new thread for each task, nginx implements | |
2870 a <link doc="../ngx_core_module.xml" id="thread_pool"/> strategy. | |
2871 Multiple thread pools may be configured intended for different purposes | |
2872 (for example, performing I/O on different sets of disks). | |
2873 Each thread pool is created on start and contains a limited number of threads | |
2874 that process a queue of tasks. | |
2875 When a task is completed, a predefined completion handler is called. | |
2876 </para> | |
2877 | |
2878 <para> | |
2879 The <literal>src/core/ngx_thread_pool.h</literal> header file contains | |
2880 corresponding definitions: | |
2881 <programlisting> | |
2882 struct ngx_thread_task_s { | |
2883 ngx_thread_task_t *next; | |
2884 ngx_uint_t id; | |
2885 void *ctx; | |
2886 void (*handler)(void *data, ngx_log_t *log); | |
2887 ngx_event_t event; | |
2888 }; | |
2889 | |
2890 typedef struct ngx_thread_pool_s ngx_thread_pool_t; | |
2891 | |
2892 ngx_thread_pool_t *ngx_thread_pool_add(ngx_conf_t *cf, ngx_str_t *name); | |
2893 ngx_thread_pool_t *ngx_thread_pool_get(ngx_cycle_t *cycle, ngx_str_t *name); | |
2894 | |
2895 ngx_thread_task_t *ngx_thread_task_alloc(ngx_pool_t *pool, size_t size); | |
2896 ngx_int_t ngx_thread_task_post(ngx_thread_pool_t *tp, ngx_thread_task_t *task); | |
2897 | |
2898 </programlisting> | |
2899 At configuration time, a module willing to use threads has to obtain a | |
2900 reference to thread pool by calling | |
2901 <literal>ngx_thread_pool_add(cf, name)</literal> which will either create a | |
2902 new thread pool with given <literal>name</literal> or return a reference | |
2903 to an existing one if a pool with such name already exists. | |
2904 </para> | |
2905 | |
2906 <para> | |
2907 At runtime, the <literal>ngx_thread_task_post(tp, task)</literal> function | |
2908 is used to add a <literal>task</literal> into a queue of a thread pool | |
2909 <literal>tp</literal>. | |
2910 | |
2911 The <literal>ngx_thread_task_t</literal> structure contains all necessary | |
2912 to execute user function in thread, pass parameters and setup completion | |
2913 handler: | |
2914 <programlisting> | |
2915 typedef struct { | |
2916 int foo; | |
2917 } my_thread_ctx_t; | |
2918 | |
2919 | |
2920 static void | |
2921 my_thread_func(void *data, ngx_log_t *log) | |
2922 { | |
2923 my_thread_ctx_t *ctx = data; | |
2924 | |
2925 /* this function is executed in a separate thread */ | |
2926 } | |
2927 | |
2928 | |
2929 static void | |
2930 my_thread_completion(ngx_event_t *ev) | |
2931 { | |
2932 my_thread_ctx_t *ctx = ev->data; | |
2933 | |
2934 /* executed in nginx event loop */ | |
2935 } | |
2936 | |
2937 | |
2938 ngx_int_t | |
2939 my_task_offload(my_conf_t *conf) | |
2940 { | |
2941 my_thread_ctx_t *ctx; | |
2942 ngx_thread_task_t *task; | |
2943 | |
2944 task = ngx_thread_task_alloc(conf->pool, sizeof(my_thread_ctx_t)); | |
2945 if (task == NULL) { | |
2946 return NGX_ERROR; | |
2947 } | |
2948 | |
2949 ctx = task->ctx; | |
2950 | |
2951 ctx->foo = 42; | |
2952 | |
2953 task->handler = my_thread_func; | |
2954 task->event.handler = my_thread_completion; | |
2955 task->event.data = ctx; | |
2956 | |
2957 if (ngx_thread_task_post(conf->thread_pool, task) != NGX_OK) { | |
2958 return NGX_ERROR; | |
2959 } | |
2960 | |
2961 return NGX_OK; | |
2962 } | |
2963 </programlisting> | |
2964 | |
2965 </para> | |
2966 | |
2967 </section> | |
2968 | |
2833 | 2969 |
2834 <section name="Modules" id="Modules"> | 2970 <section name="Modules" id="Modules"> |
2835 | 2971 |
2836 <section name="Adding new modules" id="adding_new_modules"> | 2972 <section name="Adding new modules" id="adding_new_modules"> |
2837 <para> | 2973 <para> |