簡體   English   中英

使用管道的C語言中的多線程聊天程序

[英]Multithreaded Chat Program in C using Pipes

對於班級分配,我需要開發一個程序,該程序-在兩個單獨的窗口中打開時-允許用戶在一個窗口中鍵入並在另一個窗口中顯示輸入的文本,而另一個窗口也可以鍵入並顯示其文本文本出現在第一個窗口中。

這首先使用兩個單獨的程序實現,一個程序從stdin讀取輸入,將其寫入管道,在管道上稱為fflush,然后從管道中獲取數據並將其放入stdout,然后再在stdout上調用fflush。基本上完全相反。

我在這里是因為我在努力使單個程序版本正常工作,並且不確定我是否正確理解線程。

這是我的主要功能:

int main()
{
    pthread_t threadID[2];

    pthread_mutex_init(&globalLock, NULL);

    pthread_create(&threadID[0], NULL, InputToPipe, NULL);
    pthread_create(&threadID[1], NULL, PipeToOutput, NULL);

    pthread_join(threadID[0], NULL);
    pthread_join(threadID[1], NULL);

    pthread_mutex_destroy(&globalLock);

    return 0;
}

據我了解,這將初始化一個全局鎖(我不確定是否需要),然后創建兩個線程。 第一個線程將調用InputToPipe,第二個線程將調用PipeToOutput。 兩者都應幾乎同時進入各自的功能。 進入InputToPipe(看起來像這樣)

void *InputToPipe()
{
    pthread_mutex_lock(&globalLock);
    char buffer[100];
    FILE *output = fopen("my.pipe2", "w");
    if (output == NULL)
    {
        printf("Error opening pipe\n");
        return NULL;
    }

    while (fgets(buffer, sizeof(buffer), stdin))
    {
        fputs(buffer, output);
        fflush(output);
    }
    pthread_mutex_unlock(&globalLock);

    return NULL;
}

設置了一個鎖,該鎖旨在防止程序的第二個實例訪問第一個函數。 我認為這將導致程序的第二個實例僅運行PipeToOutput函數(如下所示),

void *PipeToOutput()
{
    char buffer[100];
    FILE *input = fopen("my.pipe", "r");
    if (input == NULL)
    {
        printf("Error opening pipe\n");
        return NULL;
    }

    while (fgets(buffer, sizeof(buffer), input))
    {
        fputs(buffer, stdout);
        fflush(stdout);
    }

    return NULL;
}

但是相反,我認為它會阻止第二個程序執行任何操作,因為先連接了第一個管道,並且只有在第一個程序將其解鎖后才能執行此操作,而這在終止程序之前不會發生。 不用說,我很困惑,並且可以肯定地說,我的大多數邏輯都是關閉的,但是我無法找到有關在兩個不同的控制台窗口中使用兩個線程來運行兩個不同功能的示例或說明(除非我完全以某種方式誤解了分配,並且它只是一個函數運行兩次,但是我不認為是這種情況。 我將不勝感激,或者可以通過一些幫助修復該程序的方式來使我作為示例來了解線程在做什么,或者僅對如何實現線程及其原因進行解釋。 我知道這可能很簡單,但是我在概念上遇到了麻煩。 提前致謝。

如果想法是my.pipe用於將消息從第一個程序傳輸到第二個程序,而my.pipe2用於將消息從相反的方向傳輸,那么除了交換my.pipemy.pipe2

聽起來好像他們希望每個程序都有兩個線程,其中一個負責從第一個管道讀取並寫入stdout ,另一個負責從stdin讀取並寫入第二個管道。

在這種情況下,您的現有函數看起來是正確的,除了您根本不需要鎖-它所做的就是停止兩個線程同時運行,並且您的線程根本不共享任何狀態。 該程序的第二個副本將相同,除了交換my.pipemy.pipe2

請注意,您的InputToPipePipeToOutput函數包含一個相同的循環,僅在所使用的FILE *變量上有所不同,因此您可以將其分成自己的函數:

void FileToFile(FILE *output, FILE *input)
{
    char buffer[100];

    while (fgets(buffer, sizeof(buffer), input))
    {
        fputs(buffer, output);
        fflush(output);
    }
}

void *InputToPipe()
{
    FILE *output = fopen("my.pipe2", "w");
    if (output == NULL)
    {
        printf("Error opening pipe\n");
        return NULL;
    }

    FileToFile(output, stdin);

    fclose(output);
    return NULL;
}

void *PipeToOutput()
{
    FILE *input = fopen("my.pipe", "r");
    if (input == NULL)
    {
        printf("Error opening pipe\n");
        return NULL;
    }

    FileToFile(stdout, input);

    fclose(input);
    return NULL;
}

實際上,您可以做得更多:如果在啟動線程之前在main()進程中打開了管道,則只需將FILE *inputFILE *output變量對傳遞給線程函數,這將使您可以使用每個線程具有相同的線程功能(具有不同的參數)。

暫無
暫無

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

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