【问题标题】:C MultiThread Value not printedC 多线程值未打印
【发布时间】:2018-07-26 11:45:54
【问题描述】:

首先,这是一个完整的code

  1. 读取文件
  2. 将文件内容输入结构值
  3. 开始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;
}

现在,我问一个问题.. 我想打印最后一个线程的值。但只有“dsn”值没有打印出来..

我使用 pthread 的 mutex 来解决这个问题。但事实并非如此。

$ ./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

你能帮帮我吗? 我不明白为什么num[2]'s dsn 不显示

【问题讨论】:

  • 您误用了while(!feof(fp)) 并且可能会损坏内存,具体取决于您从sunje.conf 文件中读取的内容。如果文件中有四行,您发布的代码将尝试将 五个 条目写入您的 conf 数组。你为什么认为使用互斥锁可以解决这样的问题?那只是Easter egging
  • 嗯...我不同意你的看法。因为,Thread Num = [2] 的 dsn 在 main 函数上是 'GOLDILOCKS'。但它是线程函数上的白色值.. 很明显。所以我认为文件无关紧要。
  • 嗯...我不同意你的观点。 真的吗?您说我不明白为什么没有显示 num[2] 的 dsn,当指出导致未定义行为的明显内存损坏问题时,您“不同意”?你了解内存损坏和未定义的行为吗?
  • 我的意思是 .. conn[0] 已经存储了“GOLDILOCKS”。所有threadInfo[i].dsns 都是“GOLDILOCKS”。但是info-&gt;dsn 是“”。有时会打印 info->dsn,但也不会打印。你说的对。我也认为内存损坏。我所说的,我不同意你的观点是从文件中保存的值。我试着多想。

标签: c linux multithreading


【解决方案1】:

int result 是 4 个字节。

(void *)&amp;result 是 8 个字节。

如果第一次创建像[ int 4 byte result ][ conn[0][0] .. ] ..这样的内存结构,
返回会像[ 8 byte (void **)&amp;result ][ conn[0][4] .. ] ..

conn[0][0] ~ conn[0][3] 在哪里?此位置被 NULL(\000) 覆盖。
此程序在 NULL 值后不读取。

这是 gdb 结果。

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)

【讨论】:

    猜你喜欢
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多