Open topic with navigation

# multithread.c

The multithread.c example program is for use on the Linux platform.

This sample program demonstrates the use of multiple eduction sessions associated with a single eduction engine running in parallel.

This program takes arguments of the names of the text files to process. The program has the following stages:

1. The program creates and configures an eduction engine.
2. The program creates a worker thread for each text file.

3. The worker thread starts with the eduction engine and the text file. This worker thread:

   - creates a session associated with the eduction engine.
   - adds text from the text file to the session.
   - performs an entity extraction of the text.
4. The main program then waits for each thread to finish extraction, exit, and join.

    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <malloc.h>
    #include <string.h>
    #include <pthread.h>
    #include <edk.h>

    /*
     * Create an app that uses multiple sessions in parallel
     * Number of sessions depends on the number of input files
     */

    // Data to pass to each worker thread
    typedef struct thread_data
    {
       char* file;
          EdkEngineHandle engine;
    } t_thread_data;

    // The worker thread function
    // Creates a session using the engine handle
    // Processes the the input file
    static void* WorkProc(void* pvArgs)
    {
       t_thread_data* p = (t_thread_data*)pvArgs;
       EdkEngineHandle engine = p->engine;
       char* file = p->file;
       size_t bytesRead;
       char* buf;
       struct stat fnInfo;

       if (stat(file, &fnInfo)) {
          printf("Unable to stat input file.\n");
          return NULL;
       }
       size_t fileSize = fnInfo.st_size;
       if (!fileSize)
       {
          printf("File size of input file is zero!\n");
          return NULL;
       }

       FILE *f;
       f = fopen(file, "rb");
       if (!f)
       {
          printf("Can't open input file!\n");
          return NULL;
       }

       // Read input file to buffer
       // Note that the input must be UTF-8 encoded.
       buf = (char*)malloc(fileSize * sizeof(char));
       bytesRead = fread(buf, 1, fileSize, f);
       if (bytesRead < fileSize) {
          fclose(f);
          f = NULL;
          printf("Unable to read input file!\n");
          return NULL;
       }

       // Create a session and process the input file
       EdkError error;
       EdkSessionHandle session = NULL;
       if (EdkSuccess != (error = EdkSessionCreate(engine, &session)))
       {
          printf("Error: Unable to create session, error code = %d\n", error);
          return NULL;
       }
       if (EdkSuccess != (error = EdkAddInputText(session, buf, bytesRead, true)))
       {
          printf("Unable to add input text, error code = %d\n", error);
          return NULL;
       }
       else
       {
          while(EdkSuccess == EdkGetNextMatch(session))
          {
             // For each match found, do this ...
             const char* szMatch = NULL;
             EdkGetMatchText(session, &szMatch);
             printf("Match found: %s\n", szMatch);
          }
       }

       // Destroy the session and exit when done
       EdkSessionDestroy(session);
       session = NULL;

       free(buf);
       return NULL;
    }

    // Main function
    // Reads arguments from command line as input files
    // Creates one thread to process each input file
    int main(int argc, char **argv)
    {
       char *license;
       struct stat fnLicense;
       off_t len;
       FILE *f;
       size_t itemsRead;

       // Input files are specified at the command line
       // One thread will be created to process every input file
       if (argc <= 1) {
          printf("No input file specified.\n");
          return -1;
       }

       // Licensing
       if (stat("licensekey.dat", &fnLicense)) {
          printf("Unable to stat license file.\n");
          return -1;
       }
       len = fnLicense.st_size;
       if (!len) {
          printf("Zero byte file size for license file.\n");
          return -1;
       }
       f = fopen("licensekey.dat", "rb");
       if (!f) {
          printf("Unable to open license file.\n");
          return -1;
       }
       license = (char*)malloc(len+1);
       itemsRead = fread(license, 1, len, f);
       *(license+len) = '\0';
       fclose(f);
       if (itemsRead < (size_t)len) {
          free(license);
          printf("Unable to read license.\n");
          return -1;
       }
       if (!license) {
          return -1;
       }
       printf("INFO: License read.\n");

       // Create the eduction engine
       EdkError error;
       EdkEngineHandle engine = NULL;
       if (EdkSuccess != (error = EdkEngineCreate(&engine)))
       {
          printf("Error: Can't create engine, error code = %d.\n", error);
          return -1;
       }

       if (EdkSuccess != (error = EdkSetLicenseKey(engine, license))) {
          printf("Error: Can't set license key, error code = %d.\n", error);
          free(license);
          EdkEngineDestroy(engine);
          return -1;
       }
       printf("INFO: License validated.\n");
       free(license);

       // Load the resource file - change if necessary
       if (EdkSuccess != (error = EdkLoadResourceFile(engine, "company_eng.ecr")))
       {
          printf("Error: Can't load resource file, error code = %d.\n", error);
          EdkEngineDestroy(engine);
          return -1;
       }
       printf("INFO: Resource file loaded.\n");

       // Add target entity - change if necessary
       if (EdkSuccess != (error = EdkAddTargetEntity(engine, "company/name/eng")))
       {
          printf("Error: Can't add entity, error cdoe = %d.\n", error);
          EdkEngineDestroy(engine);
          return -1;
       }
       printf("INFO: Entity added.\n");

       // Prepare the worker threads
       size_t         nThreads = argc - 1;
       pthread_t*     threadId     = (pthread_t*)calloc(nThreads, sizeof(pthread_t));
       void* tmp = calloc(nThreads, sizeof(t_thread_data));
       t_thread_data* threadData = (t_thread_data*)tmp;
       int ii = 0;
       pthread_attr_t attr;
       pthread_attr_init(&attr);
       pthread_attr_setstacksize(&attr, 128000);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

       // Start the threads
       // Each thread uses a session to process an input file
       for(ii=0;ii<nThreads;ii++)
       {
          threadData[ii].engine = engine;
          threadData[ii].file = argv[ii + 1];
          pthread_create(&threadId[ii], &attr, WorkProc, (void*)&threadData[ii]);
       }

       // Join the threads when done
       for (ii = 0; ii < nThreads; ii++)
       {
          if (threadId[ii])
          {
             void *pvres;
             pthread_join(threadId[ii], &pvres);
          }
       }

       free(threadId);
       free(threadData);
       EdkEngineDestroy(engine);
       printf("INFO: Done\n");

       return 1;
    }

© 2013-2017 Hewlett Packard Enterprise Development LP | Send documentation feedback to HPE Close Send documentation feedback To open the configured email client on this computer, open an email window. Otherwise, copy the information below to a web mail client, and send this email to AutonomyTPFeedback@hpe.com. We appreciate your feedback! Product: Topic Title: Help Topic: Feedback:

_HP_HTML5_bannerTitle.htm