C语言 将参数传递给 pthread

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2657994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:11:52  来源:igfitidea点击:

Passing parameter to pthread

cmultithreadingunixpthreads

提问by Andrei Ciobanu

I have the following code:

我有以下代码:

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

#define NUM_THREADS 100

struct thread_param {
    char *f1;
    char *f2;
    int x;
};

void *thread_function(void *arg){
    printf("%d\n", ((struct thread_param*)arg)->x);
}

int main(int argc, char *argvs[]){
    int i, thread_cr_res = 0, thread_join_res;
    pthread_t *threads;
    threads = malloc(100 * sizeof(*threads));
    if(threads == NULL){
        fprintf(stderr,"MALLOC THREADS ERROR");
        return (-1);
    }
    for(i = 0; i < NUM_THREADS; i++){
        struct thread_param *tp;
        if((tp = malloc(sizeof(*tp))) == NULL){
            fprintf(stderr,"MALLOC THREAD_PARAM ERROR");
            return (-1);
        }
        tp->f1 = "f1";
        tp->f2 = "f2";
        tp->x = i;
        thread_cr_res = pthread_create(&threads[i], 
                    NULL, 
                    thread_function, 
                    (void*)tp);
        if(thread_cr_res != 0){
            fprintf(stderr,"THREAD CREATE ERROR");
            return (-1);
        }
    }
    return (0);
}

What i want to achieve, is to print all the numbers from 0 to 99, from threads. Also i am experimenting a way to pass a structure as a thread input parameter.

我想要实现的是从线程打印从 0 到 99 的所有数字。我也在试验一种将结构作为线程输入参数传递的方法。

What i am finding curios, is that not all the numbers are shown, eg:

我发现古玩的是,并非所有数字都显示出来,例如:

 ./a.out | grep 9
9
19
29
39
49

And sometimes some numbers are shown twice:

有时某些数字会显示两次:

...
75
74
89
77
78
79
91
91

Can you please explain me why is this happening ? No errors are shown.

你能解释一下为什么会这样吗?没有错误显示。

LATER EDIT:I've rewritten the code as @Yasir suggested, using a pthread_join. The new code looks like this:

后期编辑:我已经按照@Yasir 的建议重写了代码,使用pthread_join. 新代码如下所示:

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

#define NUM_THREADS 100

struct thread_param {
    char *f1;
    char *f2;
    int x;
};

void *thread_function(void *arg){
    printf("%d\n", ((struct thread_param*)arg)->x);
}

int main(int argc, char *argvs[]){
    int i, thread_cr_res = 0, thread_join_res;
    pthread_t *threads;
    threads = malloc(100 * sizeof(*threads));
    if(threads == NULL){
        fprintf(stderr,"MALLOC THREADS ERROR");
        return (-1);
    }
    for(i = 0; i < NUM_THREADS; i++){
        struct thread_param *tp;
        if((tp = malloc(sizeof(*tp))) == NULL){
            fprintf(stderr,"MALLOC THREAD_PARAM ERROR");
            return (-1);
        }
        tp->f1 = "f1";
        tp->f2 = "f2";
        tp->x = i;
        thread_cr_res = pthread_create(&threads[i], 
                    NULL, 
                    thread_function, 
                    (void*)tp);
        if(thread_cr_res != 0){
            fprintf(stderr,"THREAD CREATE ERROR");
            return (-1);
        }
    }
    /* Later edit, joining the threads */
    for (i = 0; i < NUM_THREADS; i++){
        thread_join_res = pthread_join(threads[i], NULL);
        if(thread_join_res != 0){
            fprintf(stderr, "JOIN ERROR");
            return (-1);
        }       
    }
    return (0);
}

After:

后:

./a.out | sort
0
1
10
11
12
13
14
15
16
17
18
19
2
20
21
22
23
24
25
26
27
28
29
3
30
31
32
33
34
35
36
37
38
39
4
40
41
42
43
44
45
46
47
48
49
5
50
51
52
53
54
55
56
57
58
59
6
60
61
62
63
64
65
66
67
68
69
7
70
71
72
73
74
75
76
77
78
79
8
80
81
82
83
84
85
86
87
88
89
9
90
91
92
93
94
95
96
97
98
99

The code is acting like it should. Still I cannot explain myself why the first version of the code was outputting duplicates.

代码就像它应该的那样。我仍然无法解释为什么代码的第一个版本输出重复。

采纳答案by Yasir Arsanukaev

Use int pthread_join(pthread_t thread, void **value_ptr)to wait for threads termination in order to get all results before main thread exit. Also because of sizeof(*tp)you end up with size of pointer to this struct which is 4 bytes long on 32 bit system. This could possibly rewrite other structures in memory. sizeof(thread_param)would make more sense to me. Also tp->f1 = "f1";refers to one constant string. I. e. you don't savea string in structure but rather used the same buffer for all your thread_paramstructures. This would be unsafe if "f1"is a pointer to variable buffer.

使用int pthread_join(pthread_t thread, void **value_ptr)等待线程终止,以获得主线程退出之前的所有结果。也因为sizeof(*tp)你最终得到了指向这个结构的指针的大小,它在 32 位系统上是 4 个字节长。这可能会重写内存中的其他结构。sizeof(thread_param)对我来说更有意义。也tp->f1 = "f1";指一个常量字符串。IE。您不会在结构中保存字符串,而是对所有thread_param结构使用相同的缓冲区。如果"f1"是指向变量缓冲区的指针,这将是不安全的。

UPD: Yes, comments bellow about size are correct.

UPD:是的,以下关于尺寸的评论是正确的。

回答by Yann Droneaud

The code is acting like it should. Still I cannot explain myself why the first version of the code was outputting duplicates.

代码就像它应该的那样。我仍然无法解释为什么代码的第一个版本输出重复。

This is probably related to how stdio is working across threads : in order to not corrupt the output (and generally any other stream), stdio use locking. And if your main thread exit, bad things could happen, like closing the streams, which will have to be reopened / flushed by other threads.

这可能与 stdio 如何跨线程工作有关:为了不破坏输出(以及通常的任何其他流),stdio 使用锁定。如果您的主线程退出,可能会发生不好的事情,例如关闭流,这些流必须由其他线程重新打开/刷新。

Note that, since there's locking around stdio function, there's contention and printf() call became a kind of synchronization point which is going to change how you program is working.

请注意,由于 stdio 函数周围存在锁定,因此存在争用,并且 printf() 调用成为一种同步点,它将改变您的程序工作方式。