简体   繁体   English

从一个空列表开始,我需要两个线程同时运行,在 C 的同一个列表中插入 100 万个随机整数

[英]Starting with an empty list, I need two threads running at the same time to insert 1 million random integers each on the same list in C

Starting with an empty list, I need two threads running at the same time to insert 1 million random integers each on the same list in C.从一个空列表开始,我需要两个线程同时运行,在 C 的同一个列表中插入 100 万个随机整数。 I am trying to pass the empty list to a thread being created.我正在尝试将空列表传递给正在创建的线程。 The function does not seem to recognize the previously created list. function 似乎无法识别之前创建的列表。 I believe it is because I am passing it wrong.我相信这是因为我传错了。 The error is as follows:错误如下:

error: 'my_list' undeclared (first use in this function);错误:“my_list”未声明(在此函数中首次使用); did you mean 'va_list'?你的意思是“va_list”吗? List_Insert(&my_list, 32); List_Insert(&my_list, 32);

Any advice would be appreciated.任何意见,将不胜感激。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h> 
#include <unistd.h>
#include <pthread.h>

//basic node structure
typedef struct __node_t {
    int     key;
    struct __node_t     *next;
} node_t;

//basic list structure (one used per list)
typedef struct __list_t {
    node_t      *head;
    pthread_mutex_t lock;
} list_t;


void List_Init(list_t *L) {
    L->head = NULL;
    pthread_mutex_init(&L->lock, NULL);
}

int List_Insert(list_t *L, int key) {
    pthread_mutex_lock(&L->lock);
    node_t *new = malloc(sizeof(node_t));
    if (new == NULL) {
        perror("malloc");
        pthread_mutex_unlock(&L->lock);
        return -1; //fail
    }
    new->key = key;
    new->next = L->head;
    L->head = new;
    pthread_mutex_unlock(&L->lock);
    return 0;  //success
}

int List_Lookup(list_t *L, int key) {
    pthread_mutex_lock(&L->lock);
    node_t *curr = L->head;
    while (curr) {
        if (curr->key == key) {
            pthread_mutex_unlock(&L->lock);
            return 0; //success
        }
        curr = curr->next;
    }
    pthread_mutex_unlock(&L->lock);
    return -1; //failure
}

//Ensures function executes after main
void *myThread(void *vargp) __attribute__((destructor));

int main(int argc, char *argv[]){

//Define an empty list
list_t my_list;

//Initialize the list
List_Init(&my_list);

//Create the threads
int i;
pthread_t tid;

for (i = 0; i < 2; i++)
    pthread_create(&tid, NULL, myThread, (void *)&my_list);

pthread_exit(NULL);
return 0;

}

//Function to be executed by both threads
void *myThread(void *vargp)
{
    ////FUNCTION NOT RECOGNIZING PREVIOUSLY CREATED LIST////
    printf("Inserting into list\n");
    List_Insert(&my_list, 32);

}

There's no my_list in the thread function.线程 function 中没有my_list Once you passed my_list from main, you can access it through the local variable vargp (which is what "my_list" now)从 main 传递my_list后,您可以通过局部变量vargp访问它(现在是“my_list”)

So you might be interested in:所以你可能对以下内容感兴趣:

void *myThread(void *vargp)
{
    printf("Inserting into list\n");
    List_Insert(vargp, 32);
    return NULL; // see man pthread_create
}

But...this is wrong.但是……这是错误的。 Because my_list is a local variable (local to main ).因为my_list是一个局部变量(对main来说是局部的)。 So once you exit the main thread, you can no longer access "my_list".所以一旦你退出主线程,你就不能再访问“my_list”了。 So either you'll have to wait for the threads to complete with pthread_join() calls for the two threads )For that, you'd need to save pthread_t ids of each thread - currently you're overwriting the thread ids).因此,要么您必须等待线程完成对两个线程的pthread_join()调用)为此,您需要保存每个线程的pthread_t id - 目前您正在覆盖线程 id)。

Or you'd have to allocate it with:或者您必须将其分配给:

int main(int argc, char *argv[]){

    //Define an empty list
    list_t *my_list = malloc(sizeof *my_list);

    //Initialize the list
    List_Init(my_list);

    //Create the threads
    int i;
    pthread_t tid;

    for (i = 0; i < 2; i++)
        pthread_create(&tid, NULL, myThread, my_list);

    pthread_exit(NULL);
    return 0;

} }

which you can free() later.您可以稍后free() Then you'd be able to use myThread as above.然后你就可以像上面那样使用myThread了。

You have other problems:你还有其他问题:

  • The destructor attribute will make the myThread be called again at the end. destructor属性将使myThread在最后被再次调用。 This is almost certainly not what you want.这几乎肯定不是你想要的。 You probably want the thread to carry on while the main thread exits.您可能希望线程在主线程退出时继续运行。 For that, calling pthread_exit() as currently do is sufficient.为此,像当前那样调用pthread_exit()就足够了。 So simply remove this attribute __attribute__((destructor)) from the function prototype.因此,只需从 function 原型中删除此属性__attribute__((destructor))即可。

  • You should avoid using identifier with __ as they're reserved names.您应该避免使用带有__的标识符,因为它们是保留名称。

  • Your thread function should return a pointer (as required by pthread_create API).您的线程 function 应该返回一个指针(根据pthread_create API 的要求)。

Well, my_list is a variable declared inside the main 's scope.好吧, my_list是在main的 scope 中声明的变量。 So it is not visible inside myThread function.所以它在myThread function 中是不可见的。 You can simply achieve this by using your vargp argument:您可以通过使用vargp参数简单地实现这一点:

void *myThread(void *vargp)
{
    list_t *my_list = (list_t *)vargp;
    printf("Inserting into list\n");
    List_Insert(my_list, 32);
    // Notice the missing & in the call!
}

Another problem is that the list is allocated inside the main() function's stack frame.另一个问题是列表是在main()函数的堆栈框架内分配的。 That means that after main returns, that stack frame is no longer accessible and you will have undefined behaviour.这意味着在 main 返回之后,该堆栈帧不再可访问,并且您将有未定义的行为。 You have 2 options here:您在这里有 2 个选项:

  1. Either allocate your list on heap using malloc使用malloc在堆上分配您的列表

  2. Wait for all the threads inside the main function, so the stack frame of main stays alive while your threads use that list.等待main function 中的所有线程,因此当您的线程使用该列表时, main堆栈帧保持活动状态。

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

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