2016-08-02 106 views
1


首先,我是意大利人,對於我的英語不好,感到抱歉。
無論如何,我應該這樣做:
「在C中編寫一個生成線程的程序,主要顯示從1到9的奇數,線程顯示從2到10的偶數。使主線程和線程同步信號燈」

我寫這樣的僞代碼:信號量在C.中不起作用爲什麼?

//semaphores 
semParent = free 
semChild = busy 

main 
    generate thread "child" 
    for i=1 to 9 step 2 
    P(semParent) 
    print i 
    V(semChild) 
    end for 
end main 

child 
    for i=2 to 10 step 2 
    P(semChild) 
    print i 
    V(semParent) 
end child 

這就是我如何用C語言實現:

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

pthread_mutex_t semParent; 
pthread_mutex_t semChild = PTHREAD_MUTEX_INITIALIZER; 

void* functionChild (void* arg) { 
    for(int i=2; i<=10; i+=2) { 
     pthread_mutex_lock(&semChild); 
     printf("CHILD: %d\n",i); 
     pthread_mutex_unlock(&semParent); 
    } 
    return NULL; 
} 

int main(void) {  
    pthread_t child; 
    pthread_create(&child, NULL, &functionChild, NULL); 
    pthread_mutex_init(&semParent, NULL); 
    for(int i=1; i<=9; i+=2) { 
     pthread_mutex_lock(&semParent); 
     printf("PARENT : %d\n",i); 
     pthread_mutex_unlock(&semChild); 
    } 
    pthread_join(child, NULL); 
} 

但輸出ALWA每當我運行程序時,ys都會有所不同。
有什麼問題?

我在Windows 10 64位中使用CygWin64終端。
在此先感謝。

+0

爲了實現單調增加的輸出值,您應該將「stick」從一個線程反覆傳遞給其他線程。尋找條件變量。 – Sergio

+0

@Serhio爲什麼他會使用條件變量,如果問題要求他使用信號量?他的僞代碼沒問題,只是C語言翻譯錯了。 –

+0

@PaoloBonzini互斥量經常被視爲二進制信號量(只有兩個計數器值:1或0),因此IMO翻譯是相當合法的。因爲互斥體不提供這種能力,所以需要條件變量來「解凍」等待線程。 – Sergio

回答

-1

我認爲pthread_mutex_init(&semParent, NULL)與NULL屬性和PTHREAD_MUTEX_INITIALIZER具有相同的效果,這兩個鎖都被初始化爲解鎖。您的問題雖然沒有嚴格意義上的關鍵部分。所以一個更好的解決方案應該是條件變量@Serhio提到的。您還可以檢查信號量http://www.csc.villanova.edu/~mdamian/threads/posixsem.html,它們給予更大的自由度,並且還可以具有互斥功能。

1

A pthread_mutex_t不是信號量(雖然信號量可以用作互斥量,如果您執行「V」將其初始化爲「free」)。信號量API是sem_init,sem_postsem_wait

通過在被另一個線程鎖定的互斥鎖上使用pthread_mutex_unlock,您的程序觸發了未定義的行爲。

+0

'sem _ *()'系列不是pthread API,它是爲進程間通信而設計的。 – Sergio

+0

@Serhio函數[semaphore.h'中提供](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/semaphore.h.html)是爲內部和*內部*進程通信而設計的,每[文檔](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html)。這裏使用它們非常合適。 –

+0

@AndrewHenle哦,我的壞。謝謝! – Sergio

0

這可能不是你現在遇到的問題的原因,但是你不應該在多線程程序中使用printf()。 printf()寫入緩衝區,並不總是立即打印到屏幕上。相反,您應該使用sprintf()並寫入:

char buff[20]; 
sprintf("PARENT: %d\n", i); 
write(1, buff, strlen(buff));