C将共享变量传递给pthreads

时间:2016-01-20 03:16:23

标签: c variables pthreads

我编写了以下程序来测试我对pthreads的一些假设:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> 
#include <unistd.h>

typedef struct threadArgs * ThreadArgs;

void *foo( void * argStruct );

struct threadArgs{

    int pingBool;
};

int main(int argc, char const *argv[]){

    pthread_t t1; 
    int pingBool = 1;
    int ch;
    ThreadArgs args = (ThreadArgs)malloc(sizeof(struct threadArgs));
    args->pingBool = pingBool;
    pthread_create(&t1, NULL, foo, args);

    while((ch = getchar()) != EOF ){

        if( ch == 'q' ){
            pingBool = 0;
            printf("pingBool now 0\n");
            break;
        }
    }

    pthread_join(t1, NULL);
    printf("whole program terminating\n");
    return 0;
}

void *foo( void * argStruct ){

    ThreadArgs args = argStruct;

    while( args->pingBool == 1 ){

        printf("t1 still going\n");
        sleep(1);
    }
    printf("t1 finished\n");
    return NULL;
}

基本上,它在int pingBool = 1中设置变量main(),将其传递给循环直到pingBool == 0的线程。 main()然后设置pingBool = 0,但线程继续运行。我很确定这种情况正在发生,因为pingBool在被放入结构时被复制,只有main()的本地副本被修改。

有没有办法在这样的线程之间共享和修改变量?我知道我可以简单地将pingBool设为全局变量,而不是将其传递给foo()。但是,我宁愿不这样做。

注意:如果要测试代码,则需要使用-pthread或-lpthread进行编译,具体取决于您的编译器。即gcc -Wall -Werror -pthread -o test test.c

3 个答案:

答案 0 :(得分:2)

您已经在两个线程之间共享变量 - 它只是您没有引用main中的共享副本。要引用共享副本,main需要使用args->pingBool

然而,您的代码将不正确,因为它将具有数据争用 - 不允许两个线程在不使用同步功能的情况下访问共享变量。要解决此问题,您可以使用互斥锁:

struct threadArgs {
    pthread_mutex_t lock;
    int pingBool;
};

需要初始化:

ThreadArgs args = (ThreadArgs)malloc(sizeof(struct threadArgs));
pthread_mutex_init(&args->lock, NULL);
更改main

args->pingBool应锁定互斥锁:

if ( ch == 'q' ) {
    pthread_mutex_lock(&args->lock);
    args->pingBool = 0;
    pthread_mutex_unlock(&args->lock);
    printf("pingBool now 0\n");
    break;
}

并且线程应该在读取时将其锁定:

pthread_mutex_lock(&args->lock);
while ( args->pingBool == 1 ) {
    pthread_mutex_unlock(&args->lock);
    printf("t1 still going\n");
    sleep(1);
    pthread_mutex_lock(&args->lock);
}
pthread_mutex_unlock(&args->lock);

答案 1 :(得分:0)

没关系,自己解决了。诀窍是传入一个指向原始变量的指针,并从foo()访问该指针的值。修改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> 
#include <unistd.h>

typedef struct threadArgs * ThreadArgs;

void *foo( void * argStruct );

struct threadArgs{

    int *pingBool; // Now a pointer, not an int
};

int main(int argc, char const *argv[]){

    pthread_t t1; 
    int pingBool = 1;
    int ch;
    ThreadArgs args = (ThreadArgs)malloc(sizeof(struct threadArgs));
    args->pingBool = &pingBool; // pass in a pointer to the variable, rather than the variable itself
    pthread_create(&t1, NULL, foo, args);

    while((ch = getchar()) != EOF ){

        if( ch == 'q' ){
            pingBool = 0;
            printf("pingBool now 0\n");
            break;
        }
    }

    pthread_join(t1, NULL);
    printf("whole program terminating\n");
    return 0;
}

void *foo( void * argStruct ){

    ThreadArgs args = argStruct;
    int * pingBool = args->pingBool;

    while( *pingBool == 1 ){ // access the value of the pointer

        printf("t1 still going\n");
        sleep(1);
    }
    printf("t1 finished\n");
    return NULL;
}

答案 2 :(得分:-1)

尝试通过引用传递args pthread_create()。它看起来像是:

pthread_create(&t1, NULL, foo, &args);