在尝试使线程处理程序模拟器在C中工作时遇到分段错误。我定义了以下结构:
typedef struct queue_t {
struct green_t *front, *rear;
} queue_t;
typedef struct green_cond_t {
struct queue_t *queue;
} green_cond_t;
在green.o中,我具有用于绿色条件的函数(最重要的是显示我如何初始化green_cond_t
结构):
void green_cond_init(green_cond_t *cond) {
cond = (green_cond_t *) malloc(sizeof(green_cond_t));
cond->queue = (queue_t *) malloc(sizeof(queue_t));
cond->queue->front = cond->queue->rear = NULL;
}
void green_cond_wait(green_cond_t *cond) {
green_t *susp = running;
enqueue(cond->queue, susp);
running = dequeue(ready);
swapcontext(susp->context, running->context);
}
void green_cond_signal(green_cond_t *cond) {
//check pointer reference
printf("queue pointer in green_cond_signal: %p\n", cond->queue);
if (dequeue(cond->queue) == NULL) return; //assuming segfault happens here...
green_t *init = dequeue(cond->queue);
enqueue(ready, init);
}
在test.c中:
int flag = 0;
green_cond_t cond;
void * test(void *arg) {
int id = *(int *) arg;
int loop = 4;
while (loop > 0) {
if (flag == id) {
printf("thread %d: %d\n", id, loop);
loop--;
flag = (id + 1) % 2;
//check pointer reference
printf("queue pointer in test: %p\n", &cond.queue);
green_cond_signal(&cond);
} else {
green_cond_wait(&cond);
}
}
}
int main() {
green_cond_init(&cond);
green_t g0, g1;
int a0 = 0;
int a1 = 1;
green_create(&g0, test, &a0);
green_create(&g1, test, &a1);
green_join(&g0, NULL);
green_join(&g1, NULL);
printf("done\n");
return 0;
}
运行test.c的输出:
thread 0: 4
queue pointer in test: 0x5620b9f8c450
queue pointer in green_cond_signal: (nil)
Segmentation fault (core dumped)
Program received signal SIGSEGV, Segmentation fault.
0x000055555555499f in dequeue ()
(gdb) back
#0 0x000055555555499f in dequeue ()
#1 0x0000555555554d5c in green_cond_signal ()
#2 0x0000555555554e22 in test ()
#3 0x0000555555554b04 in green_thread ()
#4 0x00007ffff7a3c6b0 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#5 0x0000000000000000 in ?? ()
由于某种原因,cond.queue
指针在第一次调用green_cond_signal()
时被设置为nil,我只是不明白为什么。我在做什么错了?
答案 0 :(得分:0)
这里
printf("queue pointer in test: %p\n", &cond.queue);
您打印cond.queue
的地址(&运算符可在整个结构上使用,您可能想这样做:(&cond)->queue
,与{{ 1}}。
在这里您打印内容:
cond.queue
在调用之前已经是printf("queue pointer in green_cond_signal: %p\n", cond->queue);
指针。
使用
NULL
以获得有意义的结果。
答案 1 :(得分:0)
您将green_cond_t
的地址传递给green_cond_init
,但是随后您覆盖了传入的指针的值:
cond = (green_cond_t *) malloc(sizeof(green_cond_t));
这意味着您正在初始化动态分配的结构,而不是全局结构。因此,当函数返回时,全局cond
仍包含来自其隐式初始化的NULL指针。
从malloc
中删除上述green_cond_init
调用,将正确初始化全局cond
。