【问题标题】:Unexpected pthread function output意外的 pthread 函数输出
【发布时间】:2017-10-06 07:22:11
【问题描述】:

我是 C 新手,正在学习信号量。我正在尝试使用 pthread、互斥锁和信号量来实现一种复杂的哲学家就餐情况。

这个想法是一个信号量,代表一个服务器,让人们坐在两张桌子上(每张桌子 4 个位置,总共 8 个)。每个表也由一个计数信号量控制。每个板由互斥锁控制以避免竞争条件。每个人都由一个线程表示。

我不明白为什么在我的代码中同一位顾客一直在吃东西,而且似乎没有增加。

代码:

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


sem_t server_sem;
int server_pshared;
int server_ret;
int server_count = 10;

sem_t tablea_sem;
int tablea_pshared;
int tablea_ret;
int tablea_count = 4;

sem_t tableb_sem;
int tableb_pshared;
int tableb_ret;
int tableb_count = 4;



//server_ret = serm_open("serverSem", O_CREAT | O_EXCL, 0644, server_count);

int customer_count = 10;
pthread_t customer[10];
//pthread_t plates[8]

int plate_count = 8;
pthread_mutex_t plates[8];


void *eat(void *i) {

    int n = *((int *) i);

    pthread_mutex_lock(&plates[n]);
    printf("Customer %d is eating\n", n);
    sleep(5);
    pthread_mutex_unlock(&plates[n]);
    printf("Customer %d is finished eating\n", n);

    return (NULL);
}

int main() {


   server_ret = sem_init(&server_sem, 1, server_count);
   tablea_ret = sem_init(&tablea_sem, 1, tablea_count);
   tableb_ret = sem_init(&tableb_sem, 1, tableb_count);

   //customer = (pthread_t[10] *)malloc(sizeof(customer));

   printf ("starting thread, semaphore is unlocked.\n");

   int i;
   int j;
   int k;




   for(i=0;i<plate_count;i++) {
      pthread_mutex_init(&plates[i],NULL);
      printf("Creating mutex for plate %d\n", i);
   }

   sem_wait(&server_sem);

   for (j=0;j<customer_count;j++) {
      //pthread_create(&customer[j],NULL,(void *)eat,&j);
      if (j<4) {
        sem_wait(&tablea_sem);
        sem_post(&tableb_sem);
        pthread_create(&customer[j],NULL,(void *)eat,&j);

        printf("Creating thread for customer %d\n", j);
      }
      else {
        sem_post(&tablea_sem);
        sem_wait(&tableb_sem);
        pthread_create(&customer[j],NULL,(void *)eat,&j);

        printf("Creating thread for customer %d\n", j);
      }

   }

   for(k=0;k<customer_count;k++) {
      pthread_join(customer[k],NULL);
      printf("Joining thread %d\n", k);
   }

   for(i=0;i<plate_count;i++) {
      pthread_mutex_destroy(&plates[i]);
   }

   return 0;
   }

控制台输出:

starting thread, semaphore is unlocked.
Creating mutex for plate 0
Creating mutex for plate 1
Creating mutex for plate 2
Creating mutex for plate 3
Creating mutex for plate 4
Creating mutex for plate 5
Creating mutex for plate 6
Creating mutex for plate 7
Creating thread for customer 0
Creating thread for customer 1
Creating thread for customer 2
Creating thread for customer 3
Creating thread for customer 4
Creating thread for customer 5
Creating thread for customer 6
Creating thread for customer 7
Creating thread for customer 8
Creating thread for customer 9
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Joining thread 0
Joining thread 1
Joining thread 2
Joining thread 3
Joining thread 4
Joining thread 5
Joining thread 6
Joining thread 7
Joining thread 8
Joining thread 9

编辑:

更新pthread_create的最后一个参数解决了客户递增的问题:

pthread_create(&customer[j],NULL,(void *)eat,(void *) (intptr_t) j);

但是,它从 6 开始,然后出现 index out of bounds 类型的问题。

现在控制台输出:

starting thread, semaphore is unlocked.
Creating mutex for plate 0
Creating mutex for plate 1
Creating mutex for plate 2
Creating mutex for plate 3
Creating mutex for plate 4
Creating mutex for plate 5
Creating mutex for plate 6
Creating mutex for plate 7
Creating thread for customer 0
Creating thread for customer 1
Creating thread for customer 2
Creating thread for customer 3
Creating thread for customer 4
Creating thread for customer 5
Creating thread for customer 6
Creating thread for customer 7
Creating thread for customer 8
Creating thread for customer 9
Customer 6 is eating
Customer 7 is eating
Illegal instruction (core dumped)

【问题讨论】:

    标签: c multithreading pthreads posix


    【解决方案1】:

    随行

    pthread_create(&customer[j],NULL,(void *)eat,&j);
    

    您将变量j 的地址作为参数传递给线程。您将相同的地址传递给 所有 个线程的相同变量。

    当循环结束时,j 的值将等于customer_count,这就是线程可能用作数组索引的值。并且它是 curseo 超出范围导致未定义的行为

    作为一种可能的解决方案,这实际上是一个可以接受将整数值转换为指针,然后在线程中将其转换回的地方。不过,这必须通过几个步骤来完成。首先在创建线程时:

    pthread_create(&customer[j],NULL,(void *)eat, (void *) (intptr_t) j);
    

    然后在线程本身:

    int n = (int) (intptr_t) i;
    

    【讨论】:

    • 这就是诀窍——但它从 6 点开始。如果您对此有所了解,请编辑我的问题。
    • @user25976 线程运行的顺序是不确定的。操作系统可以按照它认为合适的任何顺序运行它们。
    • @user25976 至于crash,需要使用调试器来定位。如果您在调试器的帮助下无法弄清楚,可能会提出一个新问题。
    • 我最初打开了一个关于该问题的线程,并认为我找到了答案。取得了错误的进展,现在又回到了原点。如果您有任何建议,请告诉我:stackoverflow.com/questions/46593112/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多