Pthread与C中的指针共享变量

时间:2016-04-13 18:50:26

标签: c pthreads

我正在使用Pthread开发一个需要共享一些变量的C项目。编写了几行代码,我刚刚意识到使用共享全局变量因缓存系统而无法正常工作。

我在stackoverflow上发现一个解决方案是将变量的地址(在我的情况下,它不止一个)传递给线程函数,它会改变什么?

由于我的线程函数调用了将修改全局变量的其他函数,所以将一个参数添加到被调用函数链中会有点痛苦,其中一个函数修改全局变量。

所以我想知道,是否可以为每个全局变量声明全局指针并使用它们来访问全局而不是真正的全局变量?

我认为这是一种肤浅的说法,但为什么它毕竟不起作用呢?

我的程序是UDP网络协议,网络看起来像环或带圆圈的简单链表。网络上的程序实例称为实体。

实体实体可以在环上插入或要求实体创建另一个环(应用),因此另一个实体将在两个环上。

接口是一种shell,命令可以导致在环上发送消息。消息被发现后,消息在整个响铃圈内循环。

shell位于主线程中,有一个用于消息处理的线程,另一个用于管理插入的线程,还有一个用于检测断环的线程。问题出在环形测试仪线程中。线程初始化一个实体的最大环号大小的全局数组(volatile short ring_check[NRING]),根据实际的环数用0初始化第一个元素,其余用-1初始化,之后它发送一个测试每个环中的消息,并在30秒的超时期间休​​眠。超时完成后,它会检查数组中的值。

消息处理的线程更改了值,当测试消息返回时,它会通过其内容检测到它并将-1写入相应的ring_check元素。

问题是在执行完毕后,测试了两个环但是检查第二个环失败了(ring_check[1] == 0)并且我真的不知道为什么......测试消息是在接收到之后立即发送消息处理后,将ring_check[1]修改为0我打印它以查看是否真的进行了更改并打印出来1.但是大约20到30秒之后,ring_tester从他的睡眠时间在0中显示ring_check[1]

short volatile ring_check[NRING+1];

// The function in the ring tester thread
static void test_ring() {
    // initialize ring_check array
    debug("ring_tester", GREEN "setting ring_check to -1...");
    char port_diff[5];
    // send test messages in each rings
    int fixed_nring = getnring();
    for (int i = fixed_nring+1; i < NRING; ++i) {
        ring_check[i] = -1;
    }
    for (int i = 0; i < fixed_nring + 1; i++) {
        debug("ring_tester", GREEN "setting ring_check %d to 0...", i);
        ring_check[i] = 0;
        itoa4(port_diff, ent.mdiff_port[i]);
        debug("ring_tester", GREEN "sending test to ring %d...", i);
        sendmessage(i, "TEST", "%s %s", ent.mdiff_ip[i], port_diff);
    }
    debug("test_ring", GREEN "timeout beginning...");
    sleep(timeout);
    debug("test_ring", GREEN "end of timeout.");

    for (int i = 0; i < fixed_nring + 1 && ring_check[i] != -1; i++) {
        debug("test_ring", GREEN "ring_check[%d]:%d", i, ring_check[i]);
        if (ring_check[i]) {
            debug("test_ring", GREEN "ring %d: checked.", i);
            continue;
        }
        else {
            debug("test_ring", GREEN "ring %d: checking failed. Ring broken...", i);
            continue;
        }
    }


 // The function called by the message treatment thread

static int action_test(char *message, char *content, int lookup_flag) {
    debug("action_test", RED "entering function...");
    if (content[15] != ' ' || content[20] != 0) {
        debug("action_test", RED "content not following the protocol."\
                "content: \"%s\"", content);
        return 1;
    }
    if (lookup_flag) {
        char mdiff_port[5];
        int fixed_nring = getnring();
        for (int i = 0; i < fixed_nring + 1 && ring_check[i] != -1; ++i) {
            itoa4(mdiff_port, ent.mdiff_port[i]);
            // find ring associated with message and actualize the checking
            if (strncmp(content, ent.mdiff_ip[i], 15) == 0 &&
                    strncmp(&content[16], mdiff_port, 4) == 0 &&
                    ring_check[i] != -1) {
                ring_check[i] = 1;
                debug("action_test", 
                        RED "correspondance found, ring_check[%d]:%d", i, ring_check[i]);
                return 0;
            }
        }
    }
    else {
        sendpacket_all(message);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您可以定义一个全局结构,例如thread_inputparam。将所有全局变量的地址放入其中并发送到所有线程,即此结构变量的地址。

int global1;
struct thread_input {
    int *g1;
   // add other globals'addresses
}thread_inputparam;
thread_inputparam.g1=&global1;