[英]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.