so true

          心懷未來,開創(chuàng)未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
          數(shù)據(jù)加載中……

          bash實現(xiàn)線程池

          #!/bin/bash
          THREAD_NUM=5
          tfile=$(mktemp /tmp/.foo.XXXXXXXX)
          rm -f $tfile
          mkfifo $tfile
          exec 9<>$tfile
          for ((i=0;i<$THREAD_NUM;i++)); do
            echo 1>&9
          done
          while read line; do
            read -u 9
            {
              echo $(date +%F_%T) $line && sleep $(($RANDOM % 5)) #do your work
              echo 1>&9
            }&
          done
          wait
          rm -f $tfile
          =========================================================
          # Job pooling for bash shell scripts
          # This script provides a job pooling functionality where you can keep up to n
          # processes/functions running in parallel so that you don't saturate a system
          # with concurrent processes.
          #
          # Got inspiration from http://stackoverflow.com/questions/6441509/how-to-write-a-process-pool-bash-shell
          #
          # Copyright (c) 2012 Vince Tse
          # with changes by Geoff Clements (c) 2014
          #
          # Permission is hereby granted, free of charge, to any person obtaining a copy
          # of this software and associated documentation files (the "Software"), to deal
          # in the Software without restriction, including without limitation the rights
          # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
          # copies of the Software, and to permit persons to whom the Software is
          # furnished to do so, subject to the following conditions:
          #
          # The above copyright notice and this permission notice shall be included in
          # all copies or substantial portions of the Software.
          #
          # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
          # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
          # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
          # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
          # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
          # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
          # THE SOFTWARE.
          # end-of-jobs marker
          job_pool_end_of_jobs="JOBPOOL_END_OF_JOBS"
          # job queue used to send jobs to the workers
          job_pool_job_queue=/tmp/job_pool_job_queue_$$
          # where to run results to
          job_pool_result_log=/tmp/job_pool_result_log_$$
          # toggle command echoing
          job_pool_echo_command=0
          # number of parallel jobs allowed. also used to determine if job_pool_init
          # has been called when jobs are queued.
          job_pool_pool_size=-1
          # \brief variable to check for number of non-zero exits
          job_pool_nerrors=0
          ################################################################################
          # private functions
          ################################################################################
          # \brief debug output
          function _job_pool_echo()
          {
          if [[ "${job_pool_echo_command}" == "1" ]]; then
          echo $@
          fi
          }
          # \brief cleans up
          function _job_pool_cleanup()
          {
          rm -f ${job_pool_job_queue} ${job_pool_result_log}
          }
          # \brief signal handler
          function _job_pool_exit_handler()
          {
          _job_pool_stop_workers
          _job_pool_cleanup
          }
          # \brief print the exit codes for each command
          # \param[in] result_log the file where the exit codes are written to
          function _job_pool_print_result_log()
          {
          job_pool_nerrors=$(grep ^ERROR "${job_pool_result_log}" | wc -l)
          cat "${job_pool_result_log}" | sed -e 's/^ERROR//'
          }
          # \brief the worker function that is called when we fork off worker processes
          # \param[in] id the worker ID
          # \param[in] job_queue the fifo to read jobs from
          # \param[in] result_log the temporary log file to write exit codes to
          function _job_pool_worker()
          {
          local id=$1
          local job_queue=$2
          local result_log=$3
          local cmd=
          local args=
          exec 7<> ${job_queue}
          while [[ "${cmd}" != "${job_pool_end_of_jobs}" && -e "${job_queue}" ]]; do
          # workers block on the exclusive lock to read the job queue
          flock --exclusive 7
          IFS=$'\v'
          read cmd args <${job_queue}
          set -- ${args}
          unset IFS
          flock --unlock 7
          # the worker should exit if it sees the end-of-job marker or run the
          # job otherwise and save its exit code to the result log.
          if [[ "${cmd}" == "${job_pool_end_of_jobs}" ]]; then
          # write it one more time for the next sibling so that everyone
          # will know we are exiting.
          echo "${cmd}" >&7
          else
          _job_pool_echo "### _job_pool_worker-${id}: ${cmd}"
          # run the job
          { ${cmd} "$@" ; }
          # now check the exit code and prepend "ERROR" to the result log entry
          # which we will use to count errors and then strip out later.
          local result=$?
          local status=
          if [[ "${result}" != "0" ]]; then
          status=ERROR
          fi
          # now write the error to the log, making sure multiple processes
          # don't trample over each other.
          exec 8<> ${result_log}
          flock --exclusive 8
          _job_pool_echo "${status}job_pool: exited ${result}: ${cmd} $@" >> ${result_log}
          flock --unlock 8
          exec 8>&-
          _job_pool_echo "### _job_pool_worker-${id}: exited ${result}: ${cmd} $@"
          fi
          done
          exec 7>&-
          }
          # \brief sends message to worker processes to stop
          function _job_pool_stop_workers()
          {
          # send message to workers to exit, and wait for them to stop before
          # doing cleanup.
          echo ${job_pool_end_of_jobs} >> ${job_pool_job_queue}
          wait
          }
          # \brief fork off the workers
          # \param[in] job_queue the fifo used to send jobs to the workers
          # \param[in] result_log the temporary log file to write exit codes to
          function _job_pool_start_workers()
          {
          local job_queue=$1
          local result_log=$2
          for ((i=0; i<${job_pool_pool_size}; i++)); do
          _job_pool_worker ${i} ${job_queue} ${result_log} &
          done
          }
          ################################################################################
          # public functions
          ################################################################################
          # \brief initializes the job pool
          # \param[in] pool_size number of parallel jobs allowed
          # \param[in] echo_command 1 to turn on echo, 0 to turn off
          function job_pool_init()
          {
          local pool_size=$1
          local echo_command=$2
          # set the global attibutes
          job_pool_pool_size=${pool_size:=1}
          job_pool_echo_command=${echo_command:=0}
          # create the fifo job queue and create the exit code log
          rm -rf ${job_pool_job_queue} ${job_pool_result_log}
          mkfifo ${job_pool_job_queue}
          touch ${job_pool_result_log}
          # fork off the workers
          _job_pool_start_workers ${job_pool_job_queue} ${job_pool_result_log}
          }
          # \brief waits for all queued up jobs to complete and shuts down the job pool
          function job_pool_shutdown()
          {
          _job_pool_stop_workers
          _job_pool_print_result_log
          _job_pool_cleanup
          }
          # \brief run a job in the job pool
          function job_pool_run()
          {
          if [[ "${job_pool_pool_size}" == "-1" ]]; then
          job_pool_init
          fi
          printf "%s\v" "$@" >> ${job_pool_job_queue}
          echo >> ${job_pool_job_queue}
          }
          # \brief waits for all queued up jobs to complete before starting new jobs
          # This function actually fakes a wait by telling the workers to exit
          # when done with the jobs and then restarting them.
          function job_pool_wait()
          {
          _job_pool_stop_workers
          _job_pool_start_workers ${job_pool_job_queue} ${job_pool_result_log}
          }
          #########################################
          # End of Job Pool
          #########################################

          #!/bin/bash  . job_pool.sh  function foobar() {     # do something     true }     # initialize the job pool to allow 3 parallel jobs and echo commands job_pool_init 3 0  # run jobs job_pool_run sleep 1 job_pool_run sleep 2 job_pool_run sleep 3 job_pool_run foobar job_pool_run foobar job_pool_run /bin/false  # wait until all jobs complete before continuing job_pool_wait  # more jobs job_pool_run /bin/false job_pool_run sleep 1 job_pool_run sleep 2 job_pool_run foobar  # don't forget to shut down the job pool job_pool_shutdown  # check the $job_pool_nerrors for the number of jobs that exited non-zero echo "job_pool_nerrors: ${job_pool_nerrors}"

          posted on 2017-07-25 20:19 so true 閱讀(271) 評論(0)  編輯  收藏 所屬分類: Linux

          主站蜘蛛池模板: 龙州县| 义马市| 区。| 孙吴县| 桦甸市| 永济市| 忻州市| 汽车| 青州市| 远安县| 马关县| 辽宁省| 金川县| 徐州市| 孝感市| 乃东县| 石棉县| 泗水县| 图们市| 贡嘎县| 山丹县| 丹棱县| 湘阴县| 神池县| 库伦旗| 兴文县| 个旧市| 会同县| 舟山市| 永寿县| 连城县| 温泉县| 南平市| 遵化市| 开封市| 金昌市| 宣武区| 定襄县| 莱西市| 德江县| 姚安县|