繁体   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

从一个空列表开始,我需要两个线程同时运行,在 C 的同一个列表中插入 100 万个随机整数。 我正在尝试将空列表传递给正在创建的线程。 function 似乎无法识别之前创建的列表。 我相信这是因为我传错了。 错误如下:

错误:“my_list”未声明(在此函数中首次使用); 你的意思是“va_list”吗? List_Insert(&my_list, 32);

任何意见,将不胜感激。

#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);

}

线程 function 中没有my_list 从 main 传递my_list后,您可以通过局部变量vargp访问它(现在是“my_list”)

所以你可能对以下内容感兴趣:

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

但是……这是错误的。 因为my_list是一个局部变量(对main来说是局部的)。 所以一旦你退出主线程,你就不能再访问“my_list”了。 因此,要么您必须等待线程完成对两个线程的pthread_join()调用)为此,您需要保存每个线程的pthread_t id - 目前您正在覆盖线程 id)。

或者您必须将其分配给:

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;

}

您可以稍后free() 然后你就可以像上面那样使用myThread了。

你还有其他问题:

  • destructor属性将使myThread在最后被再次调用。 这几乎肯定不是你想要的。 您可能希望线程在主线程退出时继续运行。 为此,像当前那样调用pthread_exit()就足够了。 因此,只需从 function 原型中删除此属性__attribute__((destructor))即可。

  • 您应该避免使用带有__的标识符,因为它们是保留名称。

  • 您的线程 function 应该返回一个指针(根据pthread_create API 的要求)。

好吧, my_list是在main的 scope 中声明的变量。 所以它在myThread function 中是不可见的。 您可以通过使用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!
}

另一个问题是列表是在main()函数的堆栈框架内分配的。 这意味着在 main 返回之后,该堆栈帧不再可访问,并且您将有未定义的行为。 您在这里有 2 个选项:

  1. 使用malloc在堆上分配您的列表

  2. 等待main function 中的所有线程,因此当您的线程使用该列表时, main堆栈帧保持活动状态。

暂无
暂无

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

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