-1

First, Here is an entire code.

  1. Read the file
  2. Input file content into structure value
  3. Begin Multithread

$ cat sunje.conf
{
    DSN:GOLDILOCKS
    UID:TEST
    PWD:test
    COMMIT INTERVAL:1
}

$ cat sh.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/time.h>

//EXEC SQL INCLUDE SQLCA;

typedef struct thread
{
    char *dsn;
    char *uid;
    char *pwd;
    char mode;
    int  num;
    int  start;
    int  end;
    int  interval;
} thread;

pthread_mutex_t mutex;
void *MultiThread(void* threadInfo);

int main(int argc, char **argv)
{
    char  s[1024];
    FILE  *fp;
    char  conn[4][1024];
    int i = 0;
    int session = 0;
    int record  = 0;
    char mode = NULL;
    //int interval;

    fp = fopen("sunje.conf", "r");
    while(!feof(fp))
    {
        fgets(s, 1024, fp);

        char *ptr = strchr(s, ':');
        if (ptr != NULL)
        {
            strcpy(conn[i], ptr + 1);
            conn[i][strlen(conn[i]) - 1] = '\0';
            //printf("conn[%d]=\"%s\"\n", i, conn[i]);
            i++;
        }
    }
    fclose(fp);

    session = atoi(argv[1]);
    record  = atoi(argv[2]);
    mode = argv[4][0];

    printf("=========================================\n");
    printf("DSN             = [%s]\n"
           "ID              = [%s]\n"
           "PW              = [%s]\n"
           "Commit Interval = [%s]\n"
           "\n"
           "Total Session   = %d\n"
           "Total Record    = %d\n"
           "Mode            = %c\n", conn[0], conn[1], conn[2], conn[3], session, record, mode);
    printf("=========================================\n");

    int init = 1;
    int init_div = record / session ;
    int init_mod = record % session ;

    if (mode == 's')
    {
        init = record;
        init_div = 0;
    }

    pthread_mutex_init(&mutex, NULL);
    thread     threadInfo[session];
    pthread_t  threadCount[session];
    i = 0;
    for ( i = 0 ; i < session ; i ++)
    {
        pthread_mutex_lock(&mutex);
        if( i != ( session - 1 ) )
        {
            threadInfo[i].dsn = conn[0];
            threadInfo[i].uid = conn[1];
            threadInfo[i].pwd = conn[2];
            threadInfo[i].interval = atoi(conn[3]);
            threadInfo[i].mode = mode;
            threadInfo[i].num  = i;
            threadInfo[i].start = init;
            threadInfo[i].end   = init + init_div - 1;
        }else
        {
            threadInfo[i].dsn = conn[0];
            threadInfo[i].uid = conn[1];
            threadInfo[i].pwd = conn[2];
            threadInfo[i].interval = atoi(conn[3]);
            threadInfo[i].mode = mode;
            threadInfo[i].num  = i;
            threadInfo[i].start = init;
            threadInfo[i].end   = init + init_div + init_mod - 1;
        }
        pthread_mutex_unlock(&mutex);
        printf("Thread Num  = [%d]\n"
               "Mode        = [%c]\n"
               "Start       = [%d]\n"
               "End         = [%d]\n"
               "Interval    = [%d]\n"
               "DSN         = [%s]\n\n"
               ,threadInfo[i].num, threadInfo[i].mode, threadInfo[i].start, threadInfo[i].end, threadInfo[i].interval, threadInfo[i].dsn);
        pthread_create ( &threadCount[i], NULL, MultiThread, (void*)&threadInfo[i] );
        init = init + init_div;
    }

    int result;
    i = 0;
    for ( i = 0 ; i < session ; i ++)
    {
        pthread_join ( threadCount[i], (void *)&result );
    }

    printf("Thread Success\n");
    return 0;
}

void *MultiThread(void* threadInfo)
{
    thread* info = (thread*)threadInfo;

//    struct timeval st, et;

    char mode;
    int num;
    int start;
    int end;
    int interval;

    mode      = info->mode;
    num       = info->num;
    start     = info->start;
    end       = info->end;
    interval  = info->interval;

    printf("num[%d] dsn[%s] uid[%s] pwd[%s] mode[%c] interval[%d] start[%d] end[%d]\n", num, info->dsn, info->uid, info->pwd, mode, interval, start, end);

    return NULL;
}

Now, I ask a question.. I want to print last thread's value. But only "dsn" value not printed..

I used mutex of pthread to solve this problem. But it was not.

$ ./sh 3 300 2 i
=========================================
DSN             = [GOLDILOCKS]
ID              = [TEST]
PW              = [test]
Commit Interval = [1]

Total Session   = 3
Total Record    = 300
Mode            = i
=========================================
Thread Num  = [0]
Mode        = [i]
Start       = [1]
End         = [100]
Interval    = [1]
DSN         = [GOLDILOCKS]

Thread Num  = [1]
Mode        = [i]
Start       = [101]
End         = [200]
Interval    = [1]
DSN         = [GOLDILOCKS]

num[0] dsn[GOLDILOCKS] uid[TEST] pwd[test] mode[i] interval[1] start[1] end[100]
Thread Num  = [2]
Mode        = [i]
Start       = [201]
End         = [300]
Interval    = [1]
DSN         = [GOLDILOCKS]

num[1] dsn[GOLDILOCKS] uid[TEST] pwd[test] mode[i] interval[1] start[101] end[200]
num[2] dsn[] uid[TEST] pwd[test] mode[i] interval[1] start[201] end[300]
Thread Success

Could you help me? I can't understand why num[2]'s dsn is not show

P.Lonnie
  • 105
  • 2
  • 11
  • 2
    Possible duplicate of [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Andrew Henle Jul 26 '18 at 11:51
  • 1
    You're misuing `while(!feof(fp))` and likely corrupting memory, depending on what you read from the `sunje.conf` file. If there are four lines in the file, the code you posted will try to write **five** entries into your `conf` array. Why would you think using a mutex would solve a problem such as this? That's just [Easter egging](http://www.catb.org/jargon/html/E/Easter-egging.html). – Andrew Henle Jul 26 '18 at 11:52
  • Well... I don't agree with you. Because, dsn of Thread Num = [2] is 'GOLDILOCKS' on main function. But it is white value on thread function.. It is obvious. So I think it doesn't matter with file. – P.Lonnie Jul 26 '18 at 13:52
  • *Well... I don't agree with you.* Really? You state *I can't understand why num[2]'s dsn is not show* and when an obvious memory-corrupting issue that causes undefined behavior is pointed out, you "don't agree"? Do you understand memory corruption and undefined behavior at all? – Andrew Henle Jul 26 '18 at 14:02
  • I mean .. conn[0] already stored "GOLDILOCKS".. And all `threadInfo[i].dsn`s are "GOLDILOCKS". But `info->dsn` is "". Sometimes info->dsn printed, but also not printed. You are right. I also think memory corrupting. What I said, _I don't agree with you_ is saved value from file. I try thinking more. – P.Lonnie Jul 26 '18 at 14:19

1 Answers1

0

int result is 4 bytes.

(void *)&result is 8 bytes.

If the memory structure made like [ int 4 byte result ][ conn[0][0] .. ] .. on first time,
the return will be like [ 8 byte (void **)&result ][ conn[0][4] .. ] ..

Where is conn[0][0] ~ conn[0][3] ? this location covered with NULL(\000).
This program doesn't read after NULL value.

Here is gdb result.

Breakpoint 1, main (argc=5, argv=0x7fffffffdbf8) at sh.gc:131 131 pthread_join ( threadCount[i], (void **)&result ); 1: conn[0] = "\000\000\000\000GOLDILOCKS", '\000' <repeats 26 times>, "\364G\336\367\377\177\000\000\000" (gdb) p &conn[0] $1 = (char (*)[50]) 0x7fffffffd5c0 (gdb) p &result $2 = (int *) 0x7fffffffd5bc (gdb)

P.Lonnie
  • 105
  • 2
  • 11