[英]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 個選項:
使用malloc
在堆上分配您的列表
等待main
function 中的所有線程,因此當您的線程使用該列表時, main
堆棧幀保持活動狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.