在随机条件下的无限 while 循环中创建 reader 和编写器线程时出现分段错误

Getting segmentation fault while creating reader and writer threads inside a infinite while loop on random condition

我正在尝试在无限 while 循环中随机创建 reader 和编写器线程(每个线程 5 个)。编写者应该等到所有 reader 都执行完毕。为此,我正在使用互斥量和条件变量。

// Global variables
int readerCount=0, writerCount=0, sharedVariable=1001;

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t write_cond = PTHREAD_COND_INITIALIZER;

reader 个线程运行 下面的函数

void *readShared(void* param)
{
    int shVariable, readers; //To copy and print global variables locally

    pthread_mutex_lock(&m);

        readerCount++;
        while(readerCount > 1)
        {
            pthread_cond_wait(&read_cond, &m);
        }
        readerCount--;
        readers = readerCount;
        shVariable = sharedVariable;

    pthread_mutex_unlock(&m);

    printf("[Reader]:  Value in shared Variable = %d\n", shVariable);
    printf("Other \"Reader\" threads present = %d\n", readers);

    pthread_mutex_lock(&m);

        if(readerCount > 0)
        {
            pthread_cond_signal(&read_cond);
        }
        else if(writerCount > 0)
        {
            pthread_cond_signal(&write_cond);
        }

    pthread_mutex_unlock(&m);
}

作者线程 运行 下面的函数:

void *writeShared(void *valueToWrite)
{
        //To copy and print global variables
    int value = *(int *)(valueToWrite), readers, shVariable;

    pthread_mutex_lock(&m);

        writerCount++;
        while(readerCount > 0 || writerCount > 1)
        {
            pthread_cond_wait(&write_cond, &m);
        }
        sharedVariable = value;
        readers = readerCount;
        shVariable = sharedVariable;
        writerCount--;

    pthread_mutex_unlock(&m);

    printf("[Writer]:  Value in shared Variable = %d\n", shVariable);
    printf("Value to write = %d\n", value);
    printf("Other \"Reader\" threads present = %d\n", readers);


    pthread_mutex_lock(&m);

        if(readerCount > 0)
        {
            pthread_cond_signal(&read_cond);
        }
        else if(writerCount > 0)
        {
            pthread_cond_signal(&write_cond);
        }

    pthread_mutex_unlock(&m);
}

主要功能:

int main()
{
    pthread_t readers[5], writers[5];
    int readerIndex=0, writerIndex=0;
    while(1)
    {
        if(5 == readerIndex && 5 == writerIndex)
        {
            break;
        }
        if(rand() % 2)
        {
            if(readerIndex < 5)
            {
                pthread_create(&readers[readerIndex++], NULL, readShared, NULL);
            }
        }
        else
        {
            if(writerIndex < 5)
            {
                pthread_create(&writers[writerIndex++], NULL, writeShared, (void*)((rand() % 1000) + 100));
            }
        }
    }
    for(int i=0; i<5; i++)
    {
        pthread_join(readers[i], NULL);
        pthread_join(writers[i], NULL);
    }
    return 0;
}

我尝试了 运行 gdb 并获得了以下信息:

Starting program: /home/abhijeet/threads/readWrite 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

[New Thread 0x7ffff77c4700 (LWP 3232)]
[Reader]:  Value in shared Variable = 1001
Other "Reader" threads present = 0

[New Thread 0x7ffff6fc3700 (LWP 3233)]
[Thread 0x7ffff77c4700 (LWP 3232) exited]

[New Thread 0x7ffff67c2700 (LWP 3234)]
[Reader]:  Value in shared Variable = 1001
Other "Reader" threads present = 0

[New Thread 0x7ffff5fc1700 (LWP 3235)]
[Thread 0x7ffff67c2700 (LWP 3234) exited]

Thread 3 "readWrite" received signal SIGSEGV, Segmentation fault.

[Switching to Thread 0x7ffff6fc3700 (LWP 3233)]
0x000055555555494a in writeShared (valueToWrite=0x36d) at PriorityReadWrite.c:13
13      int value = *(int *)(valueToWrite), readers, shVariable;

这一行:

pthread_create(&writers[writerIndex++], NULL, writeShared, (void*)((rand() % 1000) + 100));

将 100 到 1099 之间的随机整数作为参数传递给 writeShared 函数。在您使用 GDB 调试的特定调用中,随机值为 0x36d877.

这一行:

int value = *(int *)(valueToWrite)

获取传递的整数并将其解释为整数的 地址(实际上不是),导致分段错误。

要解决这个问题,您需要传入一个实际整数的地址(在 main 中创建一个 int valueToWrite[5] 的数组,然后将 &valueToWrite[writerIndex] 传递给 pthread_create(小心增加 writerIndex 你已经创建了线程)。

或者,您可以修复 writeShared 以期待整数而不是地址:

int value = (int)valueToWrite;