【发布时间】:2018-12-18 04:17:40
【问题描述】:
我的任务是实现一个 C 程序生成带有 id 的线程树,以便主线程将其 id(不是线程 id,而是由信号量管理的全局变量)推送到数据结构中,然后再创建 2 个线程然后终止不向线程传递任何参数。
它必须由共享变量管理,所以每个线程推送它的 id 然后再创建 2 个线程并在 (2^n) 留下创建的线程后终止进程停止,每个叶子线程应该推送它的 id 并打印它的线程树然后终止。
我选择一棵二叉树,我正在生成线程,但不知何故,程序在到达第一片叶子后停止,它打印它的叶子树然后退出,我不明白为什么:你能解释一下我在这里做错了什么它为什么存在? 这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>
typedef struct link{
int id;
struct link *parent;
struct link *left;
struct link *right;
}b_tree;
int id = 1;
int max_id = 0;
int n;
b_tree *t_tree = NULL;
sem_t sem, semp;
void *create_tree();
b_tree *new_node();
b_tree *search_tree(b_tree *, int);
void print_path(b_tree *);
void free_tree(b_tree *);
int main(int argc, char *argv[])
{
int r, i;
pthread_t tid;
b_tree *node;
if (argc < 2) {
fprintf(stderr, "Missing argument\n");
exit(1);
}
n = atoi(argv[1]);
sem_init(&sem, 0, 1);
sem_init(&semp, 0, 1);
for(i = 0; i <= n; i++){
max_id+=(int)pow(2,i);
}
node = new_node();
node->id = id;
t_tree = node;
id++;
for (i = 0; i < 2; i++) {
r = pthread_create(&tid, NULL, create_tree(), NULL);
if(r){
fprintf(stderr, "Thread creation failed\n");
exit(1);
}
}
pthread_exit(NULL);
}
b_tree *new_node(){
b_tree *node;
node = (b_tree *)malloc(sizeof(b_tree));
if(node == NULL){
fprintf(stderr, "Memory allocation error\n");
exit(1);
}
node->left = NULL;
node->right = NULL;
node->id = -1;
node->parent = NULL;
return node;
}
b_tree *search_tree(b_tree *root, int key){
b_tree *l = NULL, *r = NULL;
if(root == NULL){
return NULL;
}
if(root->id == key){
return root;
}
l = search_tree(root->left, key);
r = search_tree(root->right, key);
if(l != NULL && l->id == key){
return l;
}else if(r != NULL && r->id == key){
return r;
}
return NULL;
}
void *create_tree(){
b_tree *node;
int pid, i, r;
pthread_t tid;
node = new_node();
//Enter the critical section
sem_wait(&sem);
if(id <= max_id){
node->id = id;
id++;
}
sem_post(&sem);
//Exit from the critical section
pid = (int)node->id/2; //compute the parent id
//get parent and connect the tree
node->parent = search_tree(t_tree, pid);
if(node->parent != NULL){
if(node->parent->left == NULL){
node->parent->left = node;
}else{
node->parent->right = node;
}
}else{
fprintf(stderr, "No parent found\n");
exit(1);
}
//Check if it is a leaf
if(node->id >= pow(2,n) && node->id <= max_id){
sem_wait(&semp);
print_path(node);
sem_post(&semp);
if(node->id == max_id){ //if it is the last leaf
free_tree(t_tree);
}
}else{//not a leaf
for(i = 0; i < 2; i++){//create 2 more threds and terminate
r = pthread_create(&tid, NULL, create_tree(), NULL);
if(r > 0){
fprintf(stderr, "Thread creation failed\n");
exit(1);
}
}
printf("This node was not a leaf and it created 2 more threads\n");
}
pthread_exit(NULL);
}
void print_path(b_tree *leaf){
if(leaf != NULL) printf("Thread tree: ");
while(leaf != NULL){
printf("%d ", leaf->id);
leaf = leaf->parent;
}
printf("\n");
return;
}
void free_tree(b_tree *root){
if(root == NULL){
return;
}
free_tree(root->left);
free_tree(root->right);
free(root);
return;
}
【问题讨论】:
-
你做错了什么,很难理解?可能使用递归。
-
@barny 我想要做的是让每个线程通过信号量使用互斥访问全局变量 id 获取其当前值然后递增它并在树中创建一个节点搜索其父节点和连接它然后检查它是否是叶线程,如果是,它使用 print_path 方法打印路径,否则它创建 2 个新线程并终止
-
我想象你的任务的结论是递归非常非常非常非常难以成功设计、理解、调试和维护。祝你好运!
标签: c multithreading