简体   繁体   English

C编程多线程分段错误

[英]C programming Multithreading Segmentation Fault

When I run this code I just get a straight up Seg fault. 当我运行这段代码时,我只会得到一条直接的Seg错误。 I do not know how to fix it. 我不知道如何解决。 I am trying to create a simple multithreading programming. 我正在尝试创建一个简单的多线程编程。 It compiles completely fine but it when i run it by typing "./testing", the print statement "what?" 它完全可以编译,但是当我通过键入“ ./testing”,打印语句“ what?”运行它时,它可以编译。 at the beginning of the main function won't even print and just seg faults. 在主要功能的开始甚至不会打印,只是段错误。 I've been stuck on this for couple of hours now. 我已经坚持了几个小时。 Any ideas? 有任何想法吗? Thanks 谢谢

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

static pthread_mutex_t mutex1;
static pthread_mutex_t mutex2;

static int arrayX[4];
static int arrayY[4];

static pthread_t threads[20];

static void *function(void *index) {
    pthread_mutex_lock(&mutex1);
    int *in = (int *)index;
    arrayX[*in]++;
    pthread_mutex_unlock(&mutex1);

    pthread_mutex_lock(&mutex2);
    arrayY[*in]--;
    printf("X Finished");

    pthread_mutex_unlock(&mutex2);
}

void main() {
    printf("what?");
    //initialize the mutex
    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);

    //Initialize the arrayX
    int x = 0;
    for (x; x < 4; x++) {
        arrayX[x] = 0;
        printf("START arrayX[%d]: %d", x, arrayX[x]);
    }

    //Initialize the arrayY
    for (x = 0; x < 4; x++) {
        arrayY[x] = 0;
        printf("START arrayY[%d]: %d", x, arrayY[x]);
    }

    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);

    int *input = 0;
        for (x = 0; x < 20; x++) {
        *input = x % 4;
        pthread_create(&(threads[x]), NULL, function, input);
    }
}

int *input = 0 is setting the memory address of input to nullptr , therefor you can't store data in this address because it's invalid, you can simply leave it uninitialized int *input and then when you assign it to an int , the compiler would choose a suitable free memory location and assign the data to it. int *input = 0时设定的内存地址inputnullptr ,因此,你可以不将数据存储在这个地址,因为它是无效的,你可以简单地把它初始化int *input ,然后当你把它分配给int ,该编译器会选择一个合适的空闲内存位置并为其分配数据。

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

static pthread_mutex_t mutex1;
static pthread_mutex_t mutex2;
static pthread_t threads[20];
static int arrayX[4];
static int arrayY[4];

static void *function (void *index)
{
    int in = *((int *) index);
    pthread_mutex_lock (&mutex1);
    arrayX[in]++;
    pthread_mutex_unlock (&mutex1);
    pthread_mutex_lock (&mutex2);
    arrayY[in]--;
    pthread_mutex_unlock (&mutex2);
    // printf ("X Finished\n");
}

int main (int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
    int x = 0;
    int *input;

    printf ("what?\n");
    // Initialize the mutex
    pthread_mutex_init (&mutex1, NULL);
    pthread_mutex_init (&mutex2, NULL);
    // Initialize arrayX and arrayY
    memset (arrayX, 0, sizeof (arrayX));
    memset (arrayY, 0, sizeof (arrayY));
    // Increment values inside arrays
    for (x = 0; x < 20; x++)
    {
        *input = x % 4;
        pthread_create (&(threads[x]), NULL, function, input);
    }
    // Print array values
    for (x = 0; x < 4; x++) printf ("arrayX[%d]: %d\n", x, arrayX[x]);
    for (x = 0; x < 4; x++) printf ("arrayY[%d]: %d\n", x, arrayY[x]);

    return 0;
}

Edit: 编辑:

Dereferencing (which means using * operater to asign value to an already declared pointer ie *ptr = something ) an uninitialized pointer (which means declaring a pointer without assigning value to it ie int *pointer; ) is not a good pratice, although it may work but it can cause a crash sometimes, this is because the uninitialized pointer may point to a memory address that is being used by the system will cause an Undefined Behaviour and possibly a crash. 取消 引用 (这意味着使用*运算符将值赋值给已经声明的指针,即*ptr = something 未初始化的指针 (这意味着声明一个指针而不为其赋值,即int *pointer; 不是一个好习惯,尽管它可能可以正常工作,但有时可能导致崩溃,这是因为未初始化的指针可能指向系统正在使用的内存地址,这 将导致未定义行为并可能导致崩溃。 A corret approach would be to initialize the pointer to NULL or use malloc to get a valid pointer, however when you initialize a pointer to NULL you can not dereference it becuase it's an invalid pointer. 一个corret方法是初始化指针NULL或使用malloc ,当你初始化一个指针来获得一个有效的指针,但是NULL不能取消对它的引用,原因是其是一个无效的指针。

So instead of doing: 因此,与其做:

int *input;
*input = x % 4;

We can do: 我们可以做的:

int *input;
input = malloc (sizeof (int));
*input = x % 4;

When sending input pointer to one thread then changing its value and sending it to another thread, the input value would be changed in the first thread to the new value as well, this happens because you are sharing the same pointer input (therefore the same memory address) with all the threads. input指针发送到一个线程然后更改其值并将其发送到另一个线程时, input值也将在第一个线程中更改为新值,这是因为您共享相同的指针input (因此具有相同的内存)地址)与所有线程。 To make sure that every thread gets the intended input value you can do: 为了确保每个线程都能获得预期的输入值,您可以执行以下操作:

for (x = 0; x < 20; x++)
{
    // Create a new valid pointer
    input = malloc (sizeof (int));
    *input = x % 4;
    pthread_create (&(threads[x]), NULL, function, input);
}

This will pass a different pointer to each thread, However when you dynamically allocate memory using malloc for example, you have to free this allocated memory, we can do that from within each thread: 这将向每个线程传递一个不同的指针,但是,例如,当您使用malloc动态分配内存时,您必须释放此分配的内存,我们可以在每个线程内执行此操作:

static void *function (void *index)
{
    int *in = (int *) index;

    pthread_mutex_lock (&mutex1);
    arrayX[*in]++;
    pthread_mutex_unlock (&mutex1);

    pthread_mutex_lock (&mutex2);
    arrayY[*in]--;
    printf ("X Finished");
    pthread_mutex_unlock (&mutex2);

    // Freeing the allocated memory
    free (in);
}

When creating threads using pthread_creat , the main threads terminates when it hits the end of the main function without waiting for the other threads to finish work, unless you tell the main thread to wait for them, to do that we can use pthread_join : 当使用pthread_creat创建线程时,主线程会在到达main函数的末尾时终止,而无需等待其他线程完成工作,除非您告诉主线程等待它们,否则我们可以使用pthread_join

// Create new threads
for (x = 0; x < 20; x++)
{
    *input = x % 4;
    pthread_create (&(threads[x]), NULL, function, (void *) input);
}
// Wait for the threads to finish
for (x = 0; x < 20; x++)
{
    pthread_join (threads[x], NULL);
}

This will force the main thread to keep running until all the other threads has done their work before it exits. 这将迫使主线程保持运行状态,直到所有其他线程在退出之前完成工作为止。

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

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