简体   繁体   English

在GDB中运行程序与从命令行运行程序产生不同的结果

[英]Running a program in GDB gives a different result from running a program from the command line

I was solving the sleeping barber problem as a part of my school assignment. 作为学校作业的一部分,我正在解决理发师睡眠问题 It works fine when I run it with GDB, but gets stuck if I run it from the command line. 当我使用GDB运行它时,它可以正常工作,但是如果我从命令行运行它,它会卡住。 This is the code: 这是代码:

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#define MAX 5

int nr_clients, open;
sem_t sem_open1, sem_clients, sem_chair, sem_number;

void *Barber(){
    sem_wait(&sem_open1);
    printf("Barber: Opening the shop\n");
    open = 1;
    sem_post(&sem_open1);
    while(1){
        printf("Barber: Sleeping while there is no clients\n");
        sem_wait(&sem_clients);
        sem_wait(&sem_number);
        if(nr_clients > 0){
            sem_post(&sem_number);
            printf("Barber: starting to work on a client\n");
            sem_post(&sem_chair);
            sleep(1);
            sem_wait(&sem_number);
            printf("Barber: Client finished\n");
            nr_clients--;
            sem_post(&sem_number);
        } else {
            printf("Barber: Closing the shop\n");
            break;
        }
    }
}


void *Client(void *x){
    int i = *((int*)x);
    printf("%8sClient(%d): I want a haircut\n", "", i);
    sem_wait(&sem_open1);
    sem_wait(&sem_number);
    if(open == 1 && nr_clients < MAX){
        sem_post(&sem_open1);   
        printf("%8sClient(%d): entering the shop\n", "", i);
        nr_clients++;
        sem_post(&sem_number);
        sem_post(&sem_clients);
        sem_wait(&sem_chair);
        printf("%8sClient(%d): barber is working on me\n", "", i);
    } else {
        printf("No more room\n");
    }
}



int main(int argc, char const *argv[])
{
    if(sem_init(&sem_open1,0,1) == -1 || sem_init(&sem_clients,0,0) == -1
        || sem_init(&sem_chair,0,0) == -1 || sem_init(&sem_number,0,1) == -1){
        printf("ERROR!\n");
        return 1;
    }

    int nr_threads = 5+1;

    pthread_t thr_id[nr_threads];

    if(pthread_create(&thr_id[0], NULL, Barber, NULL) != 0) {
        printf("ERROR!\n");
        exit(1);
    }

    int numbers[nr_threads-1];

    for (int i = 0; i < nr_threads-1; ++i)
    {
        numbers[i] = i;
    }

    for (int i = 1; i < nr_threads; ++i)
    {
        if(pthread_create(&thr_id[i], NULL, Client, &numbers[i-1]) != 0){
            printf("ERROR!\n");
            exit(1);
        }
    }




    sleep(10);

    sem_wait(&sem_open1);
    open = 0;
    sem_post(&sem_open1);

    sem_post(&sem_clients);

    for (int i = 0; i < nr_threads; ++i)
    {
        pthread_join(thr_id[i], NULL);
    }
}

I compile it like this: 我这样编译它:

gcc -g sleeping_barber.c -o barber -lpthread

And then just start it in the command line. 然后只需在命令行中启动它即可。 Command line output: 命令行输出:

        Client(4): I want a haircut
No more room
        Client(3): I want a haircut
        Client(2): I want a haircut
        Client(1): I want a haircut
        Client(0): I want a haircut
^C

It just gets stuck there. 它只是卡在那里。

In GDB I run it like this: 在GDB中,我这样运行它:

(gdb) file barber
Reading symbols from barber...done.
(gdb) r
Starting program: /home/marko/Desktop/barber 

GDB output: GDB输出:

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff77f0700 (LWP 2808)]
Barber: Opening the shop
Barber: Sleeping while there is no clients
[New Thread 0x7ffff6fef700 (LWP 2809)]
        Client(0): I want a haircut
        Client(0): entering the shop
Barber: starting to work on a client
        Client(0): barber is working on me
[New Thread 0x7ffff67ee700 (LWP 2810)]
[Thread 0x7ffff6fef700 (LWP 2809) exited]
        Client(1): I want a haircut
        Client(1): entering the shop
[New Thread 0x7ffff5fed700 (LWP 2811)]
        Client(2): I want a haircut
        Client(2): entering the shop
[New Thread 0x7ffff57ec700 (LWP 2812)]
        Client(3): I want a haircut
        Client(3): entering the shop
[New Thread 0x7ffff4feb700 (LWP 2813)]
        Client(4): I want a haircut
        Client(4): entering the shop
Barber: Client finished
Barber: Sleeping while there is no clients
Barber: starting to work on a client
        Client(1): barber is working on me
[Thread 0x7ffff67ee700 (LWP 2810) exited]
Barber: Client finished
Barber: Sleeping while there is no clients
Barber: starting to work on a client
        Client(2): barber is working on me
[Thread 0x7ffff5fed700 (LWP 2811) exited]
Barber: Client finished
Barber: Sleeping while there is no clients
Barber: starting to work on a client
        Client(3): barber is working on me
[Thread 0x7ffff57ec700 (LWP 2812) exited]
Barber: Client finished
Barber: Sleeping while there is no clients
Barber: starting to work on a client
        Client(4): barber is working on me
[Thread 0x7ffff4feb700 (LWP 2813) exited]
Barber: Client finished
Barber: Sleeping while there is no clients
Barber: Closing the shop
[Thread 0x7ffff77f0700 (LWP 2808) exited]
[Inferior 1 (process 2804) exited normally]

Works as described in our assignment. 按照我们的作业说明进行工作。

INFO: 信息:

OS -> xubuntu-16.04.1 操作系统-> xubuntu-16.04.1

DEBUGGER -> GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1 调试-> GNU gdb(Ubuntu 7.11.1-0ubuntu1〜16.04)7.11.1

You have multiple problems in your code. 您的代码中有多个问题。

If a client cannot get into the Barber's shop, you never release the semaphores sem_open1 and sem_client again. 如果客户不能进入理发店,则永远不要释放信号sem_open1sem_client This is the reason why your threads are obviously blocked waiting for sem_open1. 这就是为什么您的线程明显等待sem_open1的原因。 You can deduct this because there is not more output after "I want a haircut". 您可以扣除这一点,因为“我要理发”之后没有更多输出。

But if we start at the beginning, we see that open must be 0 when your first thread enters the shop because your condition if(open == 1 && nr_clients < MAX) is false. 但是,如果我们从头开始,则会看到当您的第一个线程进入车间时, open必须为0,因为您的条件if(open == 1 && nr_clients < MAX)为假。 As no one incremented nr_clients yet, it must be the open part. 由于尚无人增加nr_clients ,因此它必须是open部分。

Furthermore you might just look at your output: The Barber didn't yet open the shop. 此外,您可能只看您的输出:理发师尚未打开商店。 You might add some logic to try again if the shop is closed at first attempt. 如果商店在第一次尝试关闭时,您可能会添加一些逻辑以重试。

The reason for your problem is that you assume a certain order in which your threads are executed. 出现问题的原因是您假定执行线程的特定顺序。 As you can easily see by the thread number in your output, it is not what you expected. 从输出中的线程号可以很容易地看到,这不是您期望的。 You simply cannot rely on any order. 您根本不能依靠任何命令。

To ensure that your shop is opened you need to give the Barber's thread a chance to run before you start the other threads. 为了确保您的商店开张,您需要在启动其他线程之前给理发师线程一个运行的机会。 Add some sleep() after creating your Barber. 在创建理发师后添加一些sleep()

Finally... With what I have written you might come to the conclusion that it's all about timing. 最后...根据我写的内容,您可能会得出结论,那就是所有关于时间的问题。 And timing can be very much different if you run your program in a debugger or without a debugger. 如果您是在调试器中运行程序,也可以在没有调试器的情况下运行程序,则计时可能会大不相同。

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

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