سؤال

وكنت قد كتبت بلدي وحدة stop_watch الخاصة. والتي تخلق موضوع والذهاب إلى النوم لفترة ثانية. بمجرد انتهاء ثانية فإنه سيتم استدعاء دالة رد في main.c وإعلام المستخدم انتهاء المدة.

وهذا هو بحيث يمكن للمستخدم سوف يكون لها سوى 3 ثوان لإدخال أرقام وأنها سوف تضطر إلى إدخال 5 أرقام. إذا انتهاء الوقت البرنامج يجب أن يتوقف.

و2 المشاكل. 1) إذا دخلوا الرقم في الوقت المطلوب. كيف يمكنني إلغاء الموضوع. أنا أفكر في استخدام thread_kill أو thread_cancel؟ 2) كيف يمكنني إنهاء في حلقة do_while؟ كما scanf سوف يمنع أثناء انتظار المستخدم للدخول.

وشكرا جزيلا لأي اقتراحات،

وبلادي رمز أدناه:

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

#include "stop_watch.h"

struct data_struct *g_data_struct;

void timeout_cb(int id)
{
    printf("Digit timeout\n");
    free(g_data_struct);
}

int main()
{
    pthread_t thread_id;
    unsigned int digit = 0;

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

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

    /* start timer for 3 seconds */
    g_data_struct->seconds = 3;
    g_data_struct->func_ptr = timeout_cb;
    thread_id = start_stopwatch(g_data_struct);

    do
    {
        printf("Enter digit: ");
        scanf("%d", &digit);
    }while(1);

    pthread_join(thread_id, NULL);
    printf("=== End of Program - all threads in ===\n");

    free(g_data_struct);

    return 0;
}



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

#include "stop_watch.h"

pthread_t thread_id;
static id = 10;

/* start sleeping and call the callback when seconds have expired */
static void* g_start_timer(void *args)
{
    void (*function_pointer)(int id);
    int seconds = ((struct data_struct*) args)->seconds;
    function_pointer = ((struct data_struct*) args)->func_ptr;

    sleep(seconds);

    (void) (*function_pointer)(id);

    pthread_exit(NULL);

    return 0;
}

/* Will sleep in its own thread for a period of seconds */
int start_stopwatch(struct data_struct *g_data_struct)
{
    int rc = 0;

    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");
        return 1;
    }

    return thread_id;
}

وهذا السؤال هو حول C99 دول مجلس التعاون الخليجي، من جانب الطريق.

هل كانت مفيدة؟

المحلول

وأنا لا أوصي باستخدام موضوع منفصل عن هذا في المقام الأول. لكن نظرا لأنه يبدو وكأنه ممارسة لتعلم كيفية استخدام الخيوط، سأذهب معها.

ويمكنك تعيين إشارة منطقية العالمي الذي يشير إلى ما إذا تم إدخال رقم. في g_start_timer، فقط قبل استدعاء function_pointer، تحقق ما إذا كان قد تم تعيين علامة. إذا كان، لا استدعاء الدالة.

إذا كنت ترغب في موضوع ليموت في وقت سابق، قبل أن انتهت فترة سباتها، يمكنك استخدام مزامنة مع قفل المحاولة.

وتحرير: منذ تقول انها ليست ممارسة، وأنا أذكر كيف أود أن تفعل ذلك. إما استخدام وظيفة يمكن أن مهلة أثناء انتظار المدخلات على ستدين، مثل تحديد () أو استطلاع (). أو، استخدم منبه () ليقطع. وإليك مثال باستخدام ناقوس الخطر:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

void alarm_signal(int signum)
{
}

int main()
{
    char c;
    unsigned int v = 0;
    struct sigaction act;
    puts("Enter digit: ");

    /* Register dummy handler for alarm */
    act.sa_handler = &alarm_signal;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGALRM, &act, NULL);

    /* Set timer for 3 seconds */
    alarm(3);

    /* Read the digits */
    errno = 0;
    while(0 != read(STDIN_FILENO, &c, 1))
    {
        if(c < '0' || c > '9')
            break;
        v = v*10 + c - '0';
    }
    if(errno == EINTR)
        puts("Timed out");
    else
        printf("Value is %d\n", v);
    return 0;
}

نصائح أخرى

وبالطبع يمكنك استخدام thread_cancel إلى إلغاء الموضوع. أما بالنسبة الشيء scanf، قد يفكرون في استخدام أنابيب لمحاكاة مدخلا من terminnal.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top