How to do multi-threading using shell script?? 

> Is it possible to do the muli-thread programming using shell script. If
> possible is it difficult that its better to do it in C or java?

Yes and no. If by your meaning "do threads manipulable in shell?" the answer is no, but if your intention is to scripts coroutines, these can be easily (although less efficiently) simulated with background processes.

The task is as easy (or difficult) as you want to make it. Below I include a front-end for the managing of coroutines in ksh — which probably will not be of much use to you except as a guideline ass it is most definitely beta SW and has been tested only on SunOS 4.x. Good luck.

#! /bin/echo error: only source
#*TAG:40928 4:Oct 11 1998:0644:initjmon:
# Author: Brian Hiles <bsh@iname.com>
# Copyright: (c) 1996-1998
# Description: create/delete/stat jobs information
# Name: addjob, deljob, dispatchjob, initjmon, showjob
# Sccs: @(#)libjobmon.sh 1.1 1998/01 bsh@iname.com (Brian Hiles)
# Usage: addjob [pid [tag-string] ]
# Usage: deljob [%jobid|pid]...
# Usage: dispatchjob [jobs-info]
# Usage: initjmon
# Usage: showjob [%jobid|pid]...
# Version: 0.3

#XXX trap break INT ??

#01
function addjob # [pid [tag-string]]
{       # side effects: modifies arrays _bgpid and _bgtag
        set -o noglob
        typeset IFS=' ()+-[]    ' n=$! s
        (($#>=2)) && n=$1 shift
        s="$*"
        set -- $(jobs %+)
        set -- $2
        # _bgpid[jobid]=pid, _bgtag[jobid]=tag-string
        _bgpid[${1:?}]=$n _bgtag[$1]=$s
        eval ${DIAG:+'(IFS=" "
        print -ru2 "[ $0: BGPIDS: ${_bgpid[*]}, JID %$1 ]")'}
}

#02
function deljob # [%jobid|pid]...
{       set -o noglob
        typeset IFS='
 ' n p                                  # IFS=<newline><space>
        ((!$#)) && set -- $!
        eval ${DIAG:+'(IFS=" "
        print -nru2 "[ $0: bg PIDs: ${_bgpid[*]} (delete job/pid $*) ")'}
        for n
        do      if [[ $n = %* ]]
                then    : NYI
                else    typeset -i i=-1
                        while (((i+=1) <= ${#_bgpid[*]}))
                        do      if [[ ${_bgpid[i]} = $n ]]
                                then    unset _bgpid[i]
                                        #XXXdisown $n
                                        break
                                fi
                        done
                        set -A _bgpid -- ${_bgpid[*]}
                fi
        done
        eval ${DIAG:+'(IFS=" "
        print -ru2 "=> ${_bgpid[*]} ]")'}
}

#03
function dispatchjob # [jobs-info]
{       # side effect: sets array _bginfo
        #XXX return return code of waited for job/process ??
        set -o noglob
        typeset IFS='
'                                       # IFS=<newline>
        ((!$#)) && set -- $(jobs -n)
        set -- $1                       # first line is last job invoked
        IFS=' ()+-[]    '
        set -- $*
        set -- $*                       # strip out null fields
        #ppp "$@"
        IFS=:
        if [[ :${_bgpid[*]}: = *:${_bgpid[${1?}]}:* ]]
        then    # _bginfo[] = { <jobid> <pid> <retval> [<tag-string>] }
                set -A _bginfo -- $1 ${_bgpid[$1]} $3 "${_bgtag[$1]}"
                eval ${DIAG:+'(IFS=" "
                print -ru2 "[ $0: BGINFO array: \"${_bginfo[*]}\" ]")'}
                return 0
        else    set -A _bginfo --
                return 1
        fi
}

#04
function initjmon #
{       trap    'set -o monitor #XXX+o bgnice
                trap    '\''if dispatchjob "$(jobs -n)"
                        then    # job had been added with "addjob" function
                                deljob ${_bgpid[$1]}
${DIAG:+print -ru2 [ CHLD trap: BGINFO array: "${_bginfo[*]}" ]}
${DIAG:+print -ru2}
                                #XXXdeljob ${_bginfo[1]} # doesnt work
                        else    :
                        fi
                        #XXXjobs >&- || exit    # should work, but doesnt! why?
                        #try: jobs >&-; [[ -z $(jobs) ]] && exit
                '\'' CHLD
        ' EXIT
}

#05
function showjob # [-v] [%jobid|pid]...
{       set -o noglob
        typeset IFS='
' RB=} n                                # IFS=<newline>
        typeset -i i
        [[ $1 = -v ]] && verbose=ON shift
        eval ${DIAG:+'print -ru2 [ $0: ... ]'}
        ((!$#)) && set -- ${_bgpid[*]}  # no arguments: print all jobs
        [[ $verbose = ON ]] && print job\\tpid\\ttag
        for n
        do      if [[ $n = %+([0-9]) ]]
                then    n=${n#\%} i=n-1
                elif [[ $n = +([0-9]) ]]
                then    i=0
                else    print -ru2 "$0: error: $n: not a jobid or pid"
                        continue
                fi
                #XXX@
                print "$i\t${_bgpid[i]}\t${_bgtag[i]}"
        done
}

#06 EMBEDDED MAN-PAGE FOR "src2man"
 : '
#++
NAME
        initjmon - monitor background process creation and termination

SYNOPSIS
        addjob [pid [tag-string] ]
        deljob [%jobid|pid]...
        dispatchjob [jobs-info]
        initjmon
        showjob [%jobid|pid]...

DESCRIPTION

        The problem here is that "jobs -n" (the -p option is effectively
        incompatible with the -n option) only equates returnstatus with
        jobid, and all we have is a pid, so we have to get clever by
        maintaining an array of information that map the two that is filled
        when the process is placed under job monitor control.

OPTIONS

RETURN CODE

EXAMPLE

ENVIRONMENT
        #XXX these are NOT in the environment!
        _bginfo - array of info from a bg process just terminated #XXX obs?
        _bgpid  - array of pids of background processes being monitored
        _bgtag  - array of optional user-supplied messages indexed by jobid

SEE ALSO
        coshell(3S) #XXX

BUGS

#--
'

Brian

documented on: 1999.10.12 Tue 20:06:19