简体   繁体   English

信号量似乎无法在多线程中正常工作

[英]Semaphore doesn't seem to work correctly with multiple threads

I try to write multiple threading example with C. Which is the gets number from user and sum numbers in two thread. 我尝试用C编写多线程示例。这是两个线程中来自用户的获取数和总和数。

Threads are directly away each other, front to back and back to front. 线程从前到后和从后到前彼此直接分开。

I am using semaphore to manage global variables but output shows that semaphore do not work correctly. 我正在使用信号量来管理全局变量,但是输出显示信号量无法正常工作。

What is wrong? 怎么了?

Output of code: 代码输出:

Array size? :10
Array of contents? :4 2 8 1 5 3 7 9 6 10
Thread_1 > read 4, sum is = 4 
Thread_1 > read 2, sum is = 6 
Thread_1 > read 8, sum is = 14 
Thread_1 > read 1, sum is = 15 
Thread_1 > read 5, sum is = 20 
Thread_1 > read 3, sum is = 23 
Thread_1 > read 7, sum is = 30 
Thread_1 > read 9, sum is = 39 
Thread_1 > read 6, sum is = 45 
Thread_1 > read 10, sum is = 55 
Thread_1 > End. 
Thread_2 > End. 

Code : 代码:

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

int *array; //Global integer array
int sum;    //Global sum variable
int counter = 0;

sem_t mutex;

void *front_to_back( void *val )
{
  int SIZE;
  SIZE = *((int *) val);

  while (1)
  {
    sem_wait(&mutex);

    if( counter != SIZE )
    {
      sum = sum + array[counter];

      printf("Thread_1 > read %d, sum is = %d \n", array[counter], sum);

      counter++;

    }else
    {
      printf("Thread_1 > End. \n");

      sem_post(&mutex);

      break;
    }

    sem_post(&mutex);
  }
}


void *back_to_front( void *val )
{
  int SIZE;
  SIZE = *((int *) val);

  int i=1;

  while (1)
  {
    sem_wait(&mutex);

    if( counter != SIZE )
    {
      sum = sum + array[SIZE - i];

      printf("Thread_2 > read %d, sum is = %d \n", array[SIZE - i], sum);

      counter++;
      i++;

    }else
    {
      printf("Thread_2 > End. \n");

      sem_post(&mutex);

      break;
    }

    sem_post(&mutex);
  }
}

main(){

  int SIZE;

  printf("Array size? :");
  scanf("%d", &SIZE);

  array = malloc(SIZE*sizeof(int));

  int i=0;

  printf("Array of contents? :");
  for (i ; i<SIZE ; i++)
  {
    scanf("%d", &array[i]);
  }

  pthread_t t[2];

  sem_init(&mutex, 0, 1);

  pthread_create(&t[1], NULL, front_to_back, (void *) &SIZE );
  pthread_create(&t[2], NULL, back_to_front, (void *) &SIZE );

  pthread_join(t[1],NULL);
  pthread_join(t[2],NULL);

  free(array);
  sem_destroy(&mutex);

}

You should be using t[0] and t[1] in main() : an array of size N has valid indexes in 0..N-1 , so, first, fix that. 您应该在main()使用t[0]t[1] :大小为N的数组在0..N-1具有有效索引,因此,首先解决此问题。 Here's the correct code: 这是正确的代码:

pthread_create(&t[0], NULL, front_to_back, (void *) &SIZE );
pthread_create(&t[1], NULL, back_to_front, (void *) &SIZE );

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

Ideally, you should also check if malloc() and pthread_create() succeed. 理想情况下,您还应该检查malloc()pthread_create()成功。 These functions can return with an error, and you should handle it. 这些函数可能会返回错误,您应该对其进行处理。 Your code ignores the errors (with the out-of-bounds access, you are actually lucky that it worked at all). 您的代码将忽略这些错误(通过越界访问,您实际上很幸运,它完全可以工作)。

Also, why are you using a semaphore as if it were a mutex? 另外,为什么要像使用互斥锁一样使用信号量? A semaphore is not really needed here - when you don't need the power and flexibility of a semaphore, just use a mutex. 这里实际上并不需要信号灯-当您不需要信号灯的功能和灵活性时,只需使用互斥锁即可。 One important difference is that semaphores allow you to wait on one thread and post on another, whereas a mutex must be unlocked by the thread that acquires it. 一个重要的区别是,信号量允许您在一个线程上等待而在另一个线程上发布,而互斥锁必须由获取该信号的线程解锁。

Thus, using a semaphore where a mutex would be enough may be covering up an error in your code. 因此,在互斥量足够的情况下使用信号量可能掩盖了代码中的错误。 So, I'd go ahead and use a mutex instead. 因此,我将继续使用互斥锁。 Here's the code with all of the changes: 这是所有更改的代码:

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

int *array; //Global integer array
int sum;    //Global sum variable
int counter = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *front_to_back( void *val )
{
    int SIZE;
    SIZE = *((int *) val);

    while (1)
    {
        pthread_mutex_lock(&mutex);

        if( counter != SIZE )
        {
            sum = sum + array[counter];

            printf("Thread_1 > read %d, sum is = %d \n", array[counter], sum);

            counter++;

        }else
        {
            printf("Thread_1 > End. \n");

            pthread_mutex_unlock(&mutex);

            break;
        }

        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}


void *back_to_front( void *val )
{
    int SIZE;
    SIZE = *((int *) val);

    int i=1;

    while (1)
    {
        pthread_mutex_lock(&mutex);

        if( counter != SIZE )
        {
            sum = sum + array[SIZE - i];

            printf("Thread_2 > read %d, sum is = %d \n", array[SIZE - i], sum);

            counter++;
            i++;

        }else
        {
            printf("Thread_2 > End. \n");

            pthread_mutex_unlock(&mutex);

            break;
        }

        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main(void) {

    int SIZE;

    printf("Array size? :");
    scanf("%d", &SIZE);

    array = malloc(SIZE*sizeof(int));

    int i=0;

    printf("Array of contents? :");
    for (; i<SIZE ; i++)
    {
        scanf("%d", &array[i]);
    }

    pthread_t t[2];

    pthread_create(&t[0], NULL, front_to_back, (void *) &SIZE );
    pthread_create(&t[1], NULL, back_to_front, (void *) &SIZE );

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

    free(array);

    return 0;

}

I don't see any other problems with the code at first sight. 我对代码一无所见。

Now, it seems like your problem is that you're not seeing any parallelism. 现在,看来您的问题是您没有看到任何并行性。 You should try with a bigger array. 您应该尝试使用更大的阵列。 A single thread is probably able to process a 10-element array before context switching. 在上下文切换之前,单个线程可能能够处理10个元素的数组。

UPDATE : I just tried the code with a 3000-element array. 更新 :我只是尝试使用具有3000个元素的数组的代码。 You can clearly see them executing in parallel. 您可以清楚地看到它们并行执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM