簡體   English   中英

C:使用pthreads和程序不會退出for循環

[英]C: Using pthreads and program is not exiting a for loop

我正在模擬一種設備,該設備將在時鍾具有下降沿時接收字節數據並寫入寄存器。 我創建了一個單獨的pthread,它將負責在高低之間切換時鍾。

現在我的問題是,在主線程中,控制台讓用戶鍵入一個十六進制值以寫入“設備”,然后它調用SendCommand(uint32_t addr,uint16_t data)函數來執行此操作。 由於應該在每個時鍾周期一次發送一位,因此我將它放在for循環中。 這是發送命令功能:

void SendCmd(uint32_t loadAddr, uint16_t data)
{
    dest = &loadAddr;
    int i;
    printf("%d\n\n",status);
    for(i=15; i>=0; --i) {
        pthread_cond_wait(&rising_edge, &data_lock);
        *dest = (*dest << 1)|(data & 0x8000) >> 15;
               //     ^^^^^^^^ get MSB
               //               ^^^^^ move the MSB down to the LSB, assuming the
               //                     peripheral wants the bit in the LSB.
        pthread_cond_wait(&falling_edge, &data_lock);
        data <<= 1;
        printf("%d\ti=%d\n",*dest,i);
    }
    pthread_mutex_unlock(&data_lock);
    status = ENABLED_IDLE;
}

當i = 0時,循環應退出並返回主功能,在此功能將要求用戶輸入另一個十六進制值。 但這沒有,而且我似乎無法找到為什么退出循環之前會被卡住的原因。

編輯:凍結實際上發生在函數執行之前:

int main()
{
    State status = DISABLED;
    Clock clk = LOW;
    int exit_flag = 0;
    char Command[20];
    pthread_t clk_t;
    pthread_cond_init(&en_sig, NULL);
    pthread_cond_init(&rising_edge, NULL);
    pthread_cond_init(&falling_edge, NULL);
    pthread_mutex_init(&clk_lock, NULL);
    pthread_mutex_init(&data_lock, NULL);
    pthread_create(&clk_t, NULL, simClk, NULL);
    while(!exit_flag)
    {
        if(status != ENABLED_ACTIVE)
        {
            fputs("(enable/disable/write [addr] [word_0] [word_1*]/quit): ", stdout);
            fflush(stdout);
            if ( fgets(Command, sizeof Command, stdin) != NULL )
            {
                char *newline = strchr(Command, '\n');
                if ( newline != NULL )
                {
                    *newline = '\0';
                }
            }

            if(strcasecmp(Command,"quit")==0)
            {
                printf("\nShutting Down!\n\n");
                pthread_cancel(&clk_t);
                pthread_mutex_destroy(&clk_lock);
                exit_flag = ~exit_flag;
                continue;
            }

            if(strcasecmp(Command,"enable")==0)
            {
                if(status != DISABLED)
                {
                    printf("\nSynthesizer is already enabled!\n\n");
                    continue;
                }
                status = ENABLED_IDLE;
                nanosleep(&ecsWait, NULL);
                printf("\nEnabled!\n\n");
                pthread_cond_signal(&en_sig);
                continue;
            }

            if(strcasecmp(Command,"disable")==0)
            {
                status = DISABLED;
               // pthread_mutex_lock(&clk_lock);
                printf("\nDisabled!\n\n");
                continue;
            }

            if(strcasecmp(Command,"w")==0)
            {
                if(status != ENABLED_IDLE)
                {
                    printf("\nSynthesizer is not enabled!\n\n");
                    continue;
                }
                printf("\nWriting!\n\n");
                status = ENABLED_ACTIVE;      //FREEZE OCCURS HERE!
                SendCmd(NREGISTER_ADDR,0xF13F);
                continue;
            }

            printf("Invalid command!\n");
        }
   }
    return 0;

}

問題:主線程需要先調用pthread_cond_wait 然后再另一個線程調用pthread_cond_signal 如果另一個線程在主線程等待條件之前發出了該條件的信號,則pthread_cond_wait將永遠不會返回。

因此,您需要確保事情按正確的順序進行,這就是互斥鎖的所在。您應該創建另一個線程之前鎖定互斥鎖,並且僅在完成使用條件變量后才解鎖互斥鎖。 另一個線程需要鎖定互斥鎖,向狀態發出信號並解鎖互斥鎖。

主線程的偽代碼

init mutex
lock the mutex
init condition variable
create the other thread
while ( !done )
{
   wait for condition
   do something useful after the condition is signaled 
}
unlock the mutex

當另一個線程想要發出信號時發出偽代碼

lock the mutex
signal the condition 
unlock the mutex

顯而易見的問題:“但是,如果主線程始終鎖定互斥鎖,那么另一個線程將如何獲取互斥鎖?”。 答:“ pthread_cond_wait內部解鎖互斥鎖,這就是為什么將互斥鎖傳遞給pthread_cond_wait 。”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM