C语言 如何在线程创建后获取用户输入

0sgqnhkj  于 2022-12-03  发布在  其他
关注(0)|答案(2)|浏览(120)

我正在尝试建立一个电梯模拟器程序,我开始与乘客功能。我需要为每个乘客创建一个线程,并要求他们输入他们的楼层号。我已经能够创建所需的乘客(线程),我只需要要求他们输入。但我还没有能够弄清楚
代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_PASSENGERS 5
#define floor 5
#define NUM_THREAD 6

pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; /*Mutex Initializer*/

int dest_floor;
int elevator[floor];
int current_floor;
int no_passengers;
int t, user_input;

void *passengers(void *threadid)
{
   // Getting thread ID
   long tid;
   tid = (long)threadid;
   printf("Passenger %d Kindly select your floor number :\n", tid); 
   scanf("%d\n", &user_input); // Where I ask them for input 
   // End of Getting ID

   pthread_exit(NULL);
}

int main()
{
   pthread_t thread[NUM_THREAD];
   int th;

   for (t = 1; t < NUM_THREAD; t++)
   {
      th = pthread_create(&thread[t], NULL, passengers, (void *)t);
      if (th)
      {
         printf("ERROR Creating Thread\n");
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

我尝试过:

void *passengers(void *threadid)
{
   // Getting thread ID
   long tid;
   tid = (long)threadid;
   printf("Passenger %d Kindly select your floor number :\n", tid); 
   scanf("%d\n", &user_input); // Where I ask them for input 
   // End of Getting ID

   pthread_exit(NULL);
}

我期待的是:

Passenger 2 Kindly select your floor number:2
Passenger 3 KIndly select your floor number:4
... and so on

我得到的是:

Passenger 1 Kindly select your floor number:
Passenger 2 KIndly select your floor number :
Passenger 3 Kindly select your floor number:
Passenger 4 KIndly select your floor number :
Passenger 5 Kindly select your floor number:
2
3
4
5
6

它不允许用户在提示符上输入楼层号,而是打印出所有线程,然后收集输入。

6mw9ycah

6mw9ycah1#

  • 这是根据@Lundin的评论更新的版本。谢谢 *

这里有一个版本使用了您已经定义的互斥锁,所以一次只有一个线程阅读stdin。请注意,user_input必须是passengers()中的局部变量,否则它将在线程之间共享,我已经修复了printf()%ldtid),并更改了通过arg将数据传递给线程的方式。
通常你会传递一个指针给一个结构体,这个结构体包含了所有必要的信息,我在这里也是这样做的。你必须确保每个线程都接收到这个结构体的一个不同的副本。在这个例子中,这个问题可以通过在每次调用thread_create()之前分配新的内存来解决,thread_create()在线程退出之前是free() d。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#define MAX_PASSENGERS 5
#define floor 5
#define NUM_THREAD 6

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /*Mutex Initializer*/

int dest_floor;
int elevator[floor];
int current_floor;
int no_passengers;
int t;

struct passenger_ctx    {
                long tid;
            };

void *passengers(void *ctx )
{
   // Getting thread ID
   struct passenger_ctx *p_ctx = ctx;
   long tid;
   int user_input;

   tid = p_ctx->tid;
   pthread_mutex_lock( &mutex );
   printf("Passenger %ld Kindly select your floor number :\n", tid); 
   scanf("%d", &user_input); // Where I ask them for input 
   pthread_mutex_unlock( &mutex );
   printf( "Passenger %ld selected %d\n", tid, user_input );
   // End of Getting ID

   free( p_ctx );
   pthread_exit(NULL);
}

int main()
{
   pthread_t thread[NUM_THREAD];
   int th;

   for (t = 1; t < NUM_THREAD; t++)
   {
      struct passenger_ctx *p_ctx;
      p_ctx = calloc( 1, sizeof *p_ctx );   // error check to be added
      p_ctx->tid = t;
      th = pthread_create(&thread[t], NULL, passengers, p_ctx );
      if (th)
      {
         printf("ERROR Creating Thread\n");
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

现在看起来是这样的:

Passenger 1 Kindly select your floor number :
9
Passenger 1 selected 9
Passenger 2 Kindly select your floor number :
8
Passenger 2 selected 8
Passenger 4 Kindly select your floor number :
7
Passenger 4 selected 7
Passenger 3 Kindly select your floor number :
6
Passenger 3 selected 6
Passenger 5 Kindly select your floor number :
5
Passenger 5 selected 5
d7v8vwbk

d7v8vwbk2#

线程是......多线程的。这意味着执行是并发的。你不能/不应该假设任何特定的执行顺序,因为这是由操作系统处理的。线程之间的上下文切换也是如此,它随时都可能发生。实现你想要的唯一方法是在当前线程正在执行时停止所有其他线程,这将有效地破坏使用线程的目的。
我知道这只是一个学习线程的人工学术程序,但实际程序是这样安排的,一个线程处理所有用户输入。正如评论中指出的,所有线程共享同一个stdin。所以这个程序没有太多意义。
明智的解决方案可能是在创建线程之前在main()中询问所有这些信息,然后将楼层号作为参数传递给线程。这样,您还可以练习将参数传递给线程,这一点很重要。也许可以让每个线程在启动时打印“乘客x正在y层等待”?

相关问题