运行 C 中 2 个线程中的函数问题

Problem with running a function in 2 threads in C

我编写了一个程序,其中包含一个函数,该函数可以连续打印作为参数接收的字符,并使 2 个线程 运行 该函数。该程序按预期运行并无限期地交错打印 2 个字符。这是代码:

#include <pthread.h>
#include <stdio.h>
void* print_char(void* th_param) {
        char* ch = (char*)th_param;
        while(1)
                printf("%c", *ch);
        return NULL;
}
int main() {
        char* c1 = "a";
        char* c2 = "b";
        pthread_t th_id;
        pthread_create(&th_id, NULL, &print_char, (void*)c1);
        pthread_t th_id2;
        pthread_create(&th_id2, NULL, &print_char, (void*)c2);
        return 0;
}

现在我必须修改这个程序,使打印函数也接受一个数字参数,并打印该字符的次数。我尝试的是:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct Params {
        char* ch;
        int num;
};
void* print_char(void* th_param) {
        int i;
        struct Params* par = (struct Params*)th_param;
        for(i=0; i<par->num; i++) {
                printf("%s", par->ch);
        }
        return NULL;
}
int main() {
        struct Params* p1 = (struct Params*)malloc(sizeof(struct Params));
        p1->ch = "a"; p1->num = 5;
        struct Params* p2 = (struct Params*)malloc(sizeof(struct Params));
        p2->ch = "b"; p2->num = 10;
        pthread_t th_id;
        pthread_create(&th_id, NULL, &print_char, (void*)p1);
        pthread_t th_id2;
        pthread_create(&th_id2, NULL, &print_char, (void*)p2);
        while(1) {}
        return 0;
}

但无济于事。不打印单个字符,光标只是站在那里闪烁什么都不做。我已经尝试篡改代码数小时,但没有任何效果。 请注意,该结构没有问题,因为如果我删除 for 循环并改用 while(1) 并再次无限次打印给 par->ch 的字符,程序将正常工作。

问题得到缓冲I/O。

你的main()-函数无限循环,所以进程没有正确终止(只能通过外部信号被杀死),所以stdout-缓冲区永远不会被常规进程刷新终止。

由于 stdout 默认情况下是行缓冲的,并且您的 printf() 不包含任何换行符,并且您尝试打印的字符数量小于 I/O-缓冲区,您的程序永远不会写出缓冲区,因此不会打印任何内容。

一种方法是在线程函数中的 printf() 之后添加 fflush(stdout);,或者在输出中包含 '\n'

另一种(更理智的)方法是让main()实际等待线程完成,并在完成后优雅地终止:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct Params {
        char* ch;
        int num;
};
void* print_char(void* th_param) {
        int i;
        struct Params* par = (struct Params*)th_param;
        for(i=0; i<par->num; i++) {
                printf("%s", par->ch);
        //fflush(stdout);
        }
        return NULL;
}
int main() {
        struct Params* p1 = (struct Params*)malloc(sizeof(struct Params));
        p1->ch = "a"; p1->num = 5;
        struct Params* p2 = (struct Params*)malloc(sizeof(struct Params));
        p2->ch = "b"; p2->num = 10;
        pthread_t th_id;
        pthread_create(&th_id, NULL, &print_char, (void*)p1);
        pthread_t th_id2;
        pthread_create(&th_id2, NULL, &print_char, (void*)p2);
        //while(1) {}
    pthread_join(th_id, NULL);
    pthread_join(th_id2, NULL);
    free(p1); //make LeakSanitizer happy, don't leak memory
    free(p2);
    puts(""); //one newline for command-line beautification
    fflush(stdout); //redundant after the puts(""), unless stdout is redirected to a non-interactive stream
    return 0;
}

由于你的 while 循环,stdout 永远不会被刷新

试试这个:

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

    struct Params {

           char* ch;
           int num;
    };

    void* print_char(void* th_param) {
          int i;

          struct Params* par = (struct Params*)th_param;

          for(i=0; i<par->num; i++) {
                printf("%s", par->ch);
          }

          return NULL;
    }

    int main() {

    struct Params* p1 = malloc(sizeof(struct Params));
    p1->ch = "a"; p1->num = 5;

    struct Params* p2 = malloc(sizeof(struct Params));
    p2->ch = "b"; p2->num = 10;

    pthread_t th_id;
    pthread_create(&th_id, NULL, &print_char, p1);

    pthread_t th_id2;
    pthread_create(&th_id2, NULL, &print_char, p2);

    fflush(stdout);

    while(1) {;}

    return 0;
    }

谢谢大家,使用 fflush 完成了这项工作。 要回答问我 运行 在什么平台上的人,我在 Linux 终端上 运行 这个。这是我的 OS 实验室 class 的家庭作业,pthread_create 是他们迄今为止教给我们的所有内容,pthread_join 以及更多线程管理内容将在以后的课程中出现。