2013-10-27 96 views
0
之間切換

我在學習的過程中如何操作系統的工作,開始與Linux的上樹莓派。目前,我正在編寫一個使用pthread創建多個線程並相互通信的程序。在這個程序中,會有2個線程(如果你計算main()爲3),1是寫入,另一個是讀取,兩個線程使用一個公共結構來讀寫,互斥信號通過互相發信號(通過檢查鎖,鎖定和解鎖)。間通信,線程

要檢查線程通信,請執行以下操作: 寫入線程將從名爲randStrings.txt的文件讀取,計算'e'的數量和每行的總字符數,然後將這2個數字放在一個公共結構中。

讀線程將寫入一個名爲resultStrings.txt的文件,從公共結構中讀取數據,然後寫入'e'的數字(如果e count爲!= 0),否則寫' - '的總長度那條線。

到目前爲止,我的線程可以互相交談,但是,我不能這樣做在pthread_join()去來回2個線程之間。

這裏是我的代碼:

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 
#include <string.h> 
#include <unistd.h> 

/* 
The following structure contains the necessary information 
to allow the function "dotprod" to access its input data and 
place its output into the structure. 
*/ 

typedef struct 
{ 
    int  e;  //number of e 
    int  c;  //number of character 
} DOTDATA; 

/* Define globally accessible variables and a mutex */ 

#define NUMTHRDS 1 
DOTDATA dotstr; 
pthread_t callThd[NUMTHRDS]; 

//Initialize mutex 
pthread_mutex_t mutex_write = PTHREAD_MUTEX_INITIALIZER; 
pthread_mutex_t mutex_read = PTHREAD_MUTEX_INITIALIZER; 
pthread_mutex_t mutex_critical = PTHREAD_MUTEX_INITIALIZER; 

void *writeMutex(void *arg) 
{ 

    int  count; 
    int  e_count; 
    int  term_sig; 
    FILE *readf; 
    char my_lines[100]; 
    char ch; 
    signed int numbers[2]; 
    int  i; 
    char s[50]; 
    term_sig = -1; 

    //unlock write region 
    printf("Write thread: Unlocking write mutex\n"); 
    pthread_mutex_unlock (&mutex_write); 

    //unlock critical region 
    printf("Write thread: Unlocking critical mutex\n"); 
    pthread_mutex_unlock (&mutex_critical); 

    readf = fopen("randStrings.txt", "r"); 
    if (readf == NULL){ 
     printf("Error opening file"); 
    } 
    //Read the file 
    while ((fgets(my_lines, 33, readf))!=NULL) 
    { 
     e_count = 0; 
     count = 0; 

     my_lines[sizeof(my_lines) - 1] = '\0'; 
     printf("%s\n", my_lines); 
     for (i = 0; i < sizeof(my_lines); i++){ 
      if(my_lines[i] == '\0') break; 
      else if (my_lines[i]=='e'){ 
       e_count++; 
      } 
      else{ //if (my_lines[i] >= 'a' && my_lines[i] <= 'z'){ 
       count++; 
      } 
     } 
     //lock write 
     printf("Write thread: Locking write mutex\n"); 
     while(pthread_mutex_lock (&mutex_write)!=0) 
     { 
      printf("Write thread: Locking write mutex\n"); 
     } 

     //lock critical region 
     printf("Write thread: Locking critical mutex\n"); 
     while(pthread_mutex_lock (&mutex_critical)!=0) 
     { 
      printf("Write thread: Locking critical mutex\n"); 
     } 

     printf("Write thread: Writing value\n"); 
     //write to global varibales 
     dotstr.e = e_count; 
     dotstr.c = count; 

     //unlock critical region 
     printf("Write thread: Unlocking critical mutex\n"); 
     pthread_mutex_unlock (&mutex_critical); 

     //unlock read 
     printf("Write thread: Unlocking read mutex\n"); 
     pthread_mutex_unlock (&mutex_read); 
     printf("\nParent(%d) send value: [%d, %d]\n", getpid(), e_count, count); 
     printf("Joining thread!\n"); 
     if((pthread_join(callThd[1], NULL)) !=0) 
     { 
      printf("Error joining with reading thread!\n"); 
     } 

    } 
    fclose(readf); 

    //lock write 
    printf("Write thread: Locking write, end signal, mutex\n"); 
    while(pthread_mutex_lock (&mutex_write)!=0) 
    { 
     printf("Write thread: Locking write, end signal, mutex\n"); 
    } 

    //lock critical region 
    printf("Write thread: Locking critical, end signal, mutex\n"); 
    while(pthread_mutex_lock (&mutex_critical)!=0) 
    { 
     printf("Write thread: Locking critical, end signal, mutex\n"); 
    } 

    printf("Read thread: reading value\n"); 
    //write to global variables 
    dotstr.e = term_sig; 
    dotstr.c = term_sig; 

    //unlock critical region 
    printf("Write thread: Unlocking critical, end signal, mutex\n"); 
    pthread_mutex_unlock (&mutex_critical); 

    //unlock read 
    printf("Write thread: Unlocking read, end signal, mutex\n"); 
    pthread_mutex_unlock (&mutex_read); 
    pthread_exit(NULL); 
} 

void *readMutex(void *arg) 
{ 
    char readBuffer[1000]; 
    FILE *readf1; 
    int  numbers_e; 
    int  numbers_c; 
    int  sig; 
    int  j; 
    sig--; 
    //open the result file. 
    readf1 = fopen("resultStrings.txt", "w"); 

    while(numbers_e != sig && numbers_c != sig) 
    {   
     //unlock read 
     printf("Read thread: Unlocking read mutex\n"); 
     pthread_mutex_unlock (&mutex_read); 

     //lock read 
     printf("Read thread: Locking read mutex\n"); 
     while(pthread_mutex_lock (&mutex_read)!=0) 
     { 
      printf("Read thread: Locking read mutex\n"); 
     } 

     //lock critical region 
     printf("Read thread: Locking critical mutex\n"); 
     while(pthread_mutex_lock (&mutex_critical)!=0) 
     { 
      printf("Read thread: Locking critical mutex\n"); 
     } 

     printf("Read thread: Reading value\n"); 
     //read global varibales 
     numbers_e = dotstr.e; 
     numbers_c = dotstr.c; 

     //unlock critical region 
     printf("Read thread: Unlocking critical mutex\n"); 
     pthread_mutex_unlock (&mutex_critical); 

     //unlock read 
     printf("Read thread: Unlocking write mutex\n"); 
     pthread_mutex_unlock (&mutex_write); 

     readBuffer[0] = 0;  //reset readBuffer 

     //Un-bundling data 
     printf("\nConsumer (%d) Bundle received: [%i, %i]\n", getpid(), numbers_e, numbers_c); 
     //readBuffer[0] = 0; 
     if(numbers_e!= 0) { 
      for (j = 0; j < numbers_e; j++){ 
       readBuffer[j] = 'e'; 
      } 
      readBuffer[j+1] = '\0'; 
      for (j = 0; j < sizeof(readBuffer); j++) { 
       if (readBuffer[j] == 'e'){ 
        fprintf(readf1, "%c", readBuffer[j]); 
        printf("%c", readBuffer[j]); 
       } 
      } 
      fprintf(readf1, "\n"); 
      printf("\n\n"); 
     } 
     else if(numbers_c != 0) { 
      for (j = 0; j < numbers_c; j++){ 
       readBuffer[j] = '-'; 
      } 
      readBuffer[j+1] = '\0'; 
      for (j = 0; j < sizeof(readBuffer) - 1; j++) { 
       if (readBuffer[j] == '-'){ 
        fprintf(readf1, "%c", readBuffer[j]); 
        printf("%c", readBuffer[j]); 
       } 
      } 
      fprintf(readf1, "\n"); 
      printf("\n"); 
     } 
     if((pthread_join(callThd[0], NULL)) !=0) 
     { 
      printf("Error joining with writing thread!\n"); 
     } 
    } 
    fclose(readf1); 
    pthread_exit(NULL); 
} 

// Main program 

int main (int argc, char *argv[]) 
{ 
    //other variables 
    pthread_attr_t attr; 
    void *status; 

    printf("Locking all mutexes...\n"); 
    pthread_mutex_lock (&mutex_read); 
    pthread_mutex_lock (&mutex_critical); 
    pthread_mutex_lock (&mutex_write); 


    //Threads attribute 
    pthread_attr_init(&attr); 
    //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

    //Create threads 
    printf("Creating writing thread...\n"); 
    pthread_create(&callThd[1], &attr, readMutex, NULL); 
    pthread_create(&callThd[0], &attr, writeMutex, NULL); 


    printf("Creating reading thread...\n"); 
    for(;;){ 
    } 

    printf("Program finished, deleting all mutexes...\n"); 
    pthread_mutex_destroy(&mutex_write); 
    pthread_mutex_destroy(&mutex_read); 
    pthread_mutex_destroy(&mutex_critical); 
    pthread_exit(NULL); 

} 

輸出:

Locking all mutexes... 
Creating writing thread... 
Creating reading thread... 
Write thread: Unlocking write mutex 
Write thread: Unlocking critical mutex 
kuuxfithomqjnyxqsdpagdue 

Write thread: Locking write mutex 
Write thread: Locking critical mutex 
Write thread: Writing value 
Write thread: Unlocking critical mutex 
Write thread: Unlocking read mutex 

Parent(2917) send value: [1, 24] 
Read thread: Unlocking read mutex 
Read thread: Locking read mutex 
Read thread: Locking critical mutex 
Read thread: Reading value 
Read thread: Unlocking critical mutex 
Read thread: Unlocking write mutex 

Consumer (2917) Bundle received: [1, 24] 
e 

Joining thread! 
Error joining with reading thread! 
czfnvphqnmzhunukxhjvxbyncerxjba 

Write thread: Locking write mutex 
Write thread: Locking critical mutex 
Write thread: Writing value 
Write thread: Unlocking critical mutex 
Write thread: Unlocking read mutex 

Parent(2917) send value: [1, 31] 
Joining thread! 
Error joining with reading thread! 
gzxwgojtnrnblyyshtqjrelwvif 

Write thread: Locking write mutex 
^C 

編輯2: 感謝達隆·指出我的過錯。通過在我不需要的地方使用指針,他們弄亂了我的結果。

現在我發現了另一個問題,而2個線程與在pthread_join()之間來回跳躍,它只能跳一次。讀線程完成處理來自寫線程的數據,並且寫線程仍然有更多的數據要發送,但它永遠不會再調用讀線程來做到這一點。有兩種方法可以在兩個線程之間來回切換嗎?也許有一個簡單的方法來做到這一點沒有pthread_join()?

此外,我該如何停止該程序後2個線程完成自己的工作?現在,我必須在主線上放置一個無限循環以保持它們在線程完成前不破壞所有互斥體的情況下運行,但除CTRL + C之外無法停止它們。

+2

簡化程序至少兩次。接近-1。 –

+0

您需要閱讀此處發佈問題的指導原則。 –

+0

我真的不能,我的程序中的所有循環都是從文本文件中操縱字符。出於某種原因,我的Pi不斷在字符串的末尾添加隨機字符,儘管我已經在字符串的末尾添加了'\ 0'。我要添加更多條件的循環,以防止它添加非字母的字符串,但不排除這個問題就像 – user2924223

回答

0

您正在製作大量指針( '*'字符),當你真的不需要它們時。你似乎不知道他們是爲了什麼?如果你正在使用的東西多項簡單地用「詮釋」,而不是「詮釋*」 ......