c - 当我使用 printf() 时,多线程代码产生不同的结果

标签 c multithreading pthreads mutex

我正在开发一个多线程 C 编程项目,在开始之前,我已经编写了一段练习代码。虽然是多线程写的,但是结果是顺序的。但是,如果我使用 printf,结果就像多线程一样。这是代码:

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

pthread_mutex_t myMutex;
int myInt[100];
int i=0;

void *PrintThread1()
{
    printf("this is initial of FIRST Thread\n");
    for (int j=0; j<33; j++) {
        pthread_mutex_lock(&myMutex);
        //printf("1\n");
        myInt[i]=1;
        i++;
        pthread_mutex_unlock(&myMutex);
    }
    pthread_exit(NULL);

}

void *PrintThread2()
{
    printf("this is initial of SECOND Thread\n");
    for (int j=0; j<33; j++) {
        pthread_mutex_lock(&myMutex);
        //printf("2\n");
        myInt[i]=2;
        i++;
        pthread_mutex_unlock(&myMutex);
    }

    pthread_exit(NULL);

}

void *PrintThread3()
{
    printf("this is initial of THIRD Thread\n");
    for (int j=0; j<33; j++) {
        pthread_mutex_lock(&myMutex);
        //printf("3\n");
        myInt[i]=3;
        i++;
        pthread_mutex_unlock(&myMutex);
    }

    pthread_exit(NULL);
}



int main(int argc, char *argv[])
{
    pthread_t firstThread, secondThread, thirdThread;
    //pthread_attr_t attr;
    pthread_mutex_init(&myMutex, NULL);
    //pthread_attr_init(&attr);
    //pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    int ft;
    ft = pthread_create(&firstThread, NULL, PrintThread1, NULL);
    if (ft){
        printf("ERROR; return code from pthread_create() is %d\n", ft);
        exit(-1);
    }
    ft = pthread_create(&secondThread, NULL, PrintThread2, NULL);
    if (ft){
        printf("ERROR; return code from pthread_create() is %d\n", ft);
        exit(-1);
    }
    ft = pthread_create(&thirdThread, NULL, PrintThread3, NULL);
    if (ft){
        printf("ERROR; return code from pthread_create() is %d\n", ft);
        exit(-1);
    }

    pthread_join(firstThread, NULL);
    pthread_join(secondThread, NULL);
    pthread_join(thirdThread, NULL);

    pthread_mutex_destroy(&myMutex);

    for (int j=0;j<100; j++) {
        printf("myInt[%d] = %d\n",j,myInt[j]);
    }
    printf("\n");

    //pthread_exit(NULL);
    return 0;
}

我的结果是:

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

Program ended with exit code: 0

但是,如果我在代码中注释的互斥体中使用 printf,结果是:

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

Program ended with exit code: 0

这是什么原因?

最佳答案

我认为你的模型太简单了。线程循环内只有 2 个操作。没有足够的时间将上下文从 thread#1 切换到 thread#2 再到 thread#3。尝试在每个线程循环中的 pthread_mutex_unlock(&myMutex) 之前添加 usleep(100) 。然后,我想,您会看到预期的行为。

关于c - 当我使用 printf() 时,多线程代码产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29181360/

相关文章:

c# - 在关闭主窗体之前关闭侧线程

java - 从字符串创建对象并在同步块(synchronized block)中用作监视器

c - Linux C 中带有 pthreads 的 Openmp 并行 for 循环语法

核心文件大小限制对进程具有不确定性影响

c++ - Murmurhash3_x86_128 如何处理大于 15 字节的数据?

c++ - 我的文件可以编译,但是当我尝试运行它时得到 "no such file or directory"

c++ - 如果您打算让变量在超出范围后保留,您在哪里调用delete?

c++ - 如何获取正确的线程 ID 和值

复杂的状态转换 : best practices

c - 如何将某些内容附加到逗号分隔列表(作为宏实现)并使用 C 预处理器将其转换为字符串?