Example: using COBOL in a multithreaded environment

This multithreading example consists of a C main program and two COBOL programs.

thrcob.c
A C main program that creates two COBOL threads, waits for them to finish, then exits
subd.cbl
A COBOL program that is run by the thread created by thrcob.c
sube.cbl
A second COBOL program that is run by the thread created by thrcob.c

To create and run the multithreading example, enter the following commands at an AIX shell prompt:

Source code for thrcob.c

/* Creates COBOL threads, SUBD and SUBE.
   Threads must be created with undetached state for join to work. */
typedef int (*PFN)();
#include  <pthread.h>
#include  <stdio.h>
#include  <setjmp.h>

extern int errno;
extern void *SUBD(void *);
extern void *SUBE(void *);

extern void _iwzCOBOLInit(int fcode, PFN StopFun, int *err_code, void *StopArg);
extern void _iwzCOBOLTerm(int fcode, int *err_code);

jmp_buf Jmpbuf;

int StopFun(long *stoparg)
{
        printf("inside StopFun. Got stoparg = %d\n", *stoparg);
        *stoparg = 123;
        longjmp(Jmpbuf,1);
}

long StopArg = 0;

void testrc(int rc, const char *s)
{
        if (rc != 0){
                printf("%s: Fatal error rc=%d\n",s,rc);
                exit(-1);
  }
}

void pgmy()
{
        pthread_t t1, t2;
        int rc;
        long i;
        long j;
        void *r1, *r2;
        pthread_attr_t attr;

        _iwzCOBOLInit(1, StopFun, &rc, &StopArg);
        printf( "_iwzCOBOLinit got %d\n",rc);
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);

        i = 2000;
        rc = pthread_create( &t1, &attr, &SUBD, &i);
        testrc(rc,"create 1");
        j = 1000;
        rc = pthread_create( &t2, &attr, &SUBE, &j);
        testrc(rc,"create 2");
        printf("threads are %x and %x\n",t1, t2);
  
        rc = pthread_join(t1, &r1);
        printf("join %x got %d\n",t1,rc);
        rc = pthread_join(t2, &r2);
        printf("join %x got %d\n",t2,rc);

        _iwzCOBOLTerm(1, &rc);
        printf( "_iwzCOBOLTerm expects rc=0, got rc=%d\n",rc);
}

main()
{
        if (setjmp(Jmpbuf) ==0) (
                pgmy();
        }
)

Source code for subd.cbl

PROCESS PGMNAME(MIXED)
       IDENTIFICATION DIVISION
       PROGRAM-ID. "SUBD".
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL NAMES.
           DECIMAL-POINT IS COMMA.
       INPUT-OUTPUT SECTION. 
       DATA DIVISION.
       FILE SECTION.
       Working-Storage SECTION.

       Local-Storage Section.
       01 n2 pic 9(8) comp-5 value 0.
       
       Linkage Section.
       01 n1 pic 9(8) comp-5.
       
       PROCEDURE DIVISION using by Reference n1.
           Display "In SUBD "

           perform n1 times 
              compute n2 = n2 + 1
              Display "From Thread 1: " n2
              CALL "Sleep" Using by value 1000 
           end-perform
            
           GOBACK.

Source code for sube.cbl

PROCESS PGMNAME(MIXED)
       IDENTIFICATION DIVISION.
       PROGRAM-ID. "SUBE".
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           DECIMAL-POINT IS COMMA.
       INPUT-OUTPUT SECTION.
       DATA DIVISION.
       FILE SECTION.
       Working-Storage SECTION.

       Local-Storage Section.
       01 n2 pic 9(8) comp-5 value 0.
        
       Linkage Section.
       01 n1 pic 9(8) comp-5.
        
       PROCEDURE DIVISION using by reference n1.
      
           perform n1 times 
              compute n2 = n2 + 1
              Display "From Thread 2: " n2
      *Go to sleep for 3/4 sec.
              CALL "Sleep" Using by value 750 
           end-perform
             
           GOBACK.