在C

时间:2018-02-20 02:39:14

标签: c multithreading struct pthreads

我正在制作一个程序,其中有2个线程分析数组。一个(消费者)检查索引是否为1,如果是,则将其转换为1.另一个线程(生产者)执行相同操作但是当它找到0时,它将其转换为1.

我使用了pthreads,但我认为每个线程都在创建自己的结构副本,我将它们作为参数传递。 他们应该能够看到其他线程对数组所做的更改,但这种情况并没有发生。

有人可以告诉我一种方法,让两个线程分析同一个数组吗?

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

#define SPACE 5
#define SEM_GR 1
#define SEM_RE 0

//Declaring a structure to pass the arguments to the threads.
struct arg_struct {
  int * semaphore;
  int * arr;
};

//Function that prints the array passed as a pointer.
void print_arr (int * a){
    for(int i = 0; i < SPACE; i++){
    if(i == SPACE - 1){
      printf("%d\n", *(a+i));
    }
    else printf("%d ", *(a+i));
    }
}


void * producing (void * arguments){
    sleep(2);
    printf("Producer started.\n");

    //Initializing the arguments structure to use its members.
    struct arg_struct *args = arguments;
    printf("Producer modifying array in: %x\n", args -> arr);

    //Transverse the array.
    for (int i = 0; i < SPACE; i++){
      sleep(1);

      //If the index in the array is empty, and if the semaphore is in green.
      printf("Producer checking array...\n");
      if(* (args -> arr + i) == 0 && * (args -> semaphore) == SEM_GR){
        //Sets the semaphore in red.
        * (args -> semaphore) = SEM_RE;
        printf("Producing!\n");

        //Sets the index in the array as 1.
        * (args -> arr + i) = 1;
        print_arr(args -> arr);

        //Sets the semaphore in green.
        * (args -> semaphore) = SEM_GR;

        //When the index is the last one in the array, it returns to the first position.
        if(i == SPACE - 1){
          i = 0;
        }
      }
    }
    pthread_exit(NULL);
    return NULL;
}

void * consuming (void * arguments){
    sleep(2);
    printf("Consumer started.\n");

    struct arg_struct * args = arguments;
    printf("Consumer modifying array in: %x\n", args -> arr);
    printf("Consumer checking array...\n");
    for (int i = 0; i < SPACE; i++){
      sleep(1);
      if(* (args -> arr + i) == 1 && * (args -> semaphore) == SEM_GR){
        * (args -> semaphore) = SEM_RE;
        printf("Consuming!\n");
        * (args -> arr + i) = 0;
        print_arr(args -> arr);
        * (args -> semaphore) = SEM_GR;
        if(i == SPACE - 1){
          i = 0;
        }
      }
    }
    pthread_exit(NULL);
    return NULL;
}

int main() {

    int * sem;
    sem = (int *) malloc(sizeof(int));
    * sem = SEM_GR;

    int * a;
    a = (int *) malloc(SPACE * sizeof(int));

    for (int i = 0; i < SPACE; i++) {
        a[i] = 1;
    }

    pthread_t produce, consume;
    struct arg_struct args;

    args.semaphore = sem;
    args.arr = a;

    printf("Array address: %x\n", a);
    print_arr(a);

    pthread_create(&consume, NULL, &consuming, (void *)&args);
    pthread_create(&produce, NULL, &producing, (void *)&args);
    pthread_join(produce, NULL);
    pthread_join(consume, NULL);

    return 0;
}

1 个答案:

答案 0 :(得分:2)

  

有人可以告诉我一种方法,让两个线程分析同一个数组吗?

你的两个线程似乎都在分析同一个数组。但代码中只有race conditions

为避免竞争条件,您需要同步线程。

请注意,从优化者的角度来看,a = 5; a = 6;只是a = 6;。因此,代码semaphore = RED; semaphore = GREEN;将优化为semaphore = GREEN;,除非您明确告诉编译器semaphore不是普通变量,而是专用同步原语。

与操作顺序相同。编译器和CPU可能会将操作顺序semaphore = RED; arr = 1; semaphore = GREEN;更改为semaphore = GREEN; arr = 1;,除非您明确说明顺序无关紧要或使用那些同时处理排序的同步原语。

总的来说,有多种方法和库可供同步。只需选择一个,尝试修复示例并再次提出新问题;)