5

c プログラム コンパイラ gcc

私は3つのファイルを持っています。main.c stop_watch.h および stop_watch.c

このプログラムは機能します。start_stopwatch を呼び出します。そして、時間の経過後に main.c timeout_cb() でコールバックします。実行する必要がある他のコードがあるため、メインでブロックしたくないので、これも別のスレッドで実行します。

1) g_start_timer の秒は常にゴミになります。ヒープ上に構造を作成することでこれを解決できたのではないかと思いました。とにかく私はこれを解決することができますか?ヒープに秒要素を作成することを考えていました。しかし、これはやり過ぎだと思います

2) このプログラムは問題なく動作しますが、メインの printf("=== timeout_cb: %p\n", timeout_cb); の行をコメントアウトすると、スタックダンプになります。

3) メモリを解放するのに最適な時期はいつですか。メインで解放していました。しかし、スレッドが終了する前にメモリが解放されると心配です。これにより、非常に予期しない結果が生じる可能性があります。この呼び出しの後、メモリを解放するために thread_join() を使用できると考えています。ただし、stop_watch.c で作成された thead_id を返す必要があります。stop_watch.c で作成された thread_id を返す方法はありますか

ご提案いただきありがとうございます。

main.c

/* main.c */
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>

#include "stop_watch.h"

/* call this when the time expires */
void timeout_cb()
{
    printf("=== your time is up run some job here ===\n");
}

int main()
{
    struct data_struct *g_data_struct =
        (struct data_struct*) calloc(1, sizeof(*g_data_struct));

    if(!g_data_struct)
    {
        printf("=== failed to allocate memory ===\n");
        return 0;
    }

    g_data_struct->seconds = 3;
    g_data_struct->func_ptr = timeout_cb;

    //  printf("=== timeout_cb: %p\n", timeout_cb);

    start_stopwatch(g_data_struct);

    // free(g_data_struct);
    printf("=== End of Program - all threads in ===\n");

    pthread_exit(NULL);

    return 0;
}

stop_watch.h

/* stop_watch.h */
struct data_struct
{
    int seconds;
    void (*func_ptr)(void);
};
void start_stopwatch(struct data_struct *g_data_struct);

stop_watch.c

#include <stdio.h>
#include <pthread.h>

#include "stop_watch.h"

static void* g_start_timer(void *args)
{
    void (*function_pointer)();

    int seconds = ((struct data_struct*) args)->seconds;
    function_pointer = ((struct data_struct*) args)->func_ptr;

    printf("=== go to sleep for %d\n", seconds);

    sleep(seconds);

    (void) (*function_pointer)();

    pthread_exit(NULL);

    return 0;
}

void start_stopwatch(struct data_struct *g_data_struct)
{
    pthread_t thread_id;
    int rc;

    int seconds = g_data_struct->seconds;
    printf("=== start_stopwatch(): %d\n", seconds);

    rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);

    if(rc)
        printf("=== Failed to create thread\n");
}
4

1 に答える 1

8

の行start_stopwatch()

rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);

次のようにする必要があります。

rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) g_data_struct);

最初のケースでは、本当にポインタをスレッド引数として渡したいときに、「ポインタへのポインタ」を渡しています。

データをいつ解放するかについては、多くのオプションがあります。常にスレッド データをヒープに割り当てられたブロックに渡す場合、g_start_timer()スレッド プロシージャは、データの引き出しが完了したときにそれを解放できます。これを行う場合、スレッドを開始するためのプロトコルの一部として、スレッド引数ブロックをヒープに割り当てる必要があることに注意してください。

于 2009-02-25T19:26:14.283 に答える