簡體   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