c - 多线程的 printf()

标签 c multithreading

我不理解这里 printf() 的行为。如果我锁定整个功能,那么打印出来就可以了。但是,如果我修改代码,使其只锁定具有数据依赖性的代码,一个线程永远不会结束? 这是代码:

queue_lock 是问题所在。

    void *professor_write(int *param){
        pthread_mutex_lock(&pro_id_update);
        param[0]++;
        int id = param[0];
        pthread_mutex_unlock(&pro_id_update);

        printf("STARTING Professor %d\n", id);
        //Each professor assigning <num_assignings> times
        for(int i = 0; i < param[1]; i++){
                int num_assignments; 
                if(param[5] == param[4])
                        num_assignments = param[5];
                else{
                //Random number of assignments in range min_num_assignment ~ max_num_assignment
                        num_assignments = rand() % (param[5] - param[4]) + param[4];
                }
                for(int j = 0; j < num_assignments; j++){
                        int wait_time;
                        if(param[3] == param[4])
                                wait_time = param[3];
                        else{
                        //Random wait time in range min_prof_wait ~ max_prof_wait
                                wait_time = rand() % (param[3] - param[2]) + param[2];
                        }
                        sleep(wait_time);
                        int hours;
                        if(param[7] == param[6])
                                hours = param[6];
                        else{
                        //Random hours range in min_assignment_hours ~ max_assignment_hours
                                hours = rand() % (param[7] - param[6]) + param[6];
                        }
                        struct assignment tmp;
                        tmp.hours = hours;
                        tmp.numberOfStudents = param[8];
                        tmp.prof_id = id;
                        pthread_mutex_lock(&queue_lock);
                        //queue is full wait for students to read
                        while(param[9] == count)
                                printf("full\n");
//                              pthread_cond_wait(&empty, &queue_lock);
                        fprintf(stdout, "ASSIGN Professor %d adding Assignment %d: %d Hours\n", id, in, hours);
                        queue[in] = tmp;
                        in = (in + 1) % param[9];
                        count++;

                        //signal student the queue is not empty
//                      pthread_cond_signal(&fill);
                        pthread_mutex_unlock(&queue_lock);
                }
        }
        printf("EXITING Professor %d\n", id);
        pthread_exit(0);
}

示例输出:

num_assignings: 4
min_prof_wait: 1
max_prof_wait: 5
min_num_assignments: 1
max_num_assignments: 1
min_assignment_hours: 1
max_assignment_hours: 5
num_professors: 2
num_students: 2
students_per_assignment: 2
queue_size: 256
STARTING Professor 1
STARTING Professor 2
ASSIGN Professor 2 adding Assignment 0: 4 Hours
ASSIGN Professor 1 adding Assignment 1: 4 Hours
ASSIGN Professor 1 adding Assignment 2: 2 Hours
ASSIGN Professor 2 adding Assignment 3: 2 Hours
ASSIGN Professor 2 adding Assignment 4: 4 Hours
ASSIGN Professor 1 adding Assignment 5: 4 Hours
ASSIGN Professor 2 adding Assignment 6: 1 Hours
EXITING Professor 2

输出如果锁定整个事情:

num_assignings: 4
min_prof_wait: 1
max_prof_wait: 5
min_num_assignments: 1
max_num_assignments: 1
min_assignment_hours: 1
max_assignment_hours: 5
num_professors: 2
num_students: 2
students_per_assignment: 2
queue_size: 256
STARTING Professor 1
ASSIGN Professor 1 adding Assignment 0: 2 Hours
ASSIGN Professor 1 adding Assignment 1: 1 Hours
ASSIGN Professor 1 adding Assignment 2: 3 Hours
ASSIGN Professor 1 adding Assignment 3: 4 Hours
EXITING Professor 1
STARTING Professor 2
ASSIGN Professor 2 adding Assignment 4: 4 Hours
ASSIGN Professor 2 adding Assignment 5: 2 Hours
ASSIGN Professor 2 adding Assignment 6: 4 Hours
ASSIGN Professor 2 adding Assignment 7: 1 Hours
EXITING Professor 2

最佳答案

我已经精简了一个示例应用程序,它的行为有时与您发布的问题相同。

为了重新创建它,我“忘记”加入线程 2。
您能否确保加入所有线程,并可能发布调用线程的 block ?

根据您的评论,我认为这是最有可能的。当 prof2 在 prof1 之前完成时,我的应用程序表现出相同的行为。

In some cases, the program runs as predicted. But other times, the eighth element never updated to the queue.

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

pthread_mutex_t queue_lock;
void *professor_write(void *params){

        int prof = ((int*)params)[0];
        int runs = ((int*)params)[1];
        int i;
        printf("STARTING Professor %d\n", prof);
        //Each professor assigning <num_assignings> times
        for(i = 0; i < runs; i++){

                                                sleep(rand() % (5));
                        pthread_mutex_lock(&queue_lock);
                        fprintf(stdout, "ASSIGN Professor %d adding Assignment %d:\n", prof, i);
                        pthread_mutex_unlock(&queue_lock);

        }
       printf("EXITING Professor %d\n", prof);
        pthread_exit(0);
}


int main()
{

int prof1[2]={1,4};
int prof2[2]={2,4};
pthread_t prof2_thread;
pthread_t prof1_thread;

pthread_create(&prof1_thread, NULL, professor_write, prof1);
pthread_create(&prof2_thread, NULL, professor_write, prof2);

pthread_join(prof1_thread, NULL);
//pthread_join(prof2_thread, NULL); // commented out to force error

return 0;

}

我得到这个输出,当 prof2 首先完成时成功:

STARTING Professor 1
STARTING Professor 2
ASSIGN Professor 2 adding Assignment 0:
ASSIGN Professor 1 adding Assignment 0:
ASSIGN Professor 1 adding Assignment 1:
ASSIGN Professor 2 adding Assignment 1:
ASSIGN Professor 2 adding Assignment 2:
ASSIGN Professor 2 adding Assignment 3:
EXITING Professor 2
ASSIGN Professor 1 adding Assignment 2:
ASSIGN Professor 1 adding Assignment 3:
EXITING Professor 1

或者当 prof1 首先完成时(我更改了 rand 值以使另一个线程首先完成,或者您可以交换连接。):

STARTING Professor 1
STARTING Professor 2
ASSIGN Professor 1 adding Assignment 0:
ASSIGN Professor 2 adding Assignment 0:
ASSIGN Professor 1 adding Assignment 1:
ASSIGN Professor 2 adding Assignment 1:
ASSIGN Professor 1 adding Assignment 2:
ASSIGN Professor 2 adding Assignment 2:
ASSIGN Professor 1 adding Assignment 3:
EXITING Professor 1

关于c - 多线程的 printf(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29112290/

相关文章:

c++ - 使用具有相同条件变量的不同互斥体是否有意义?

python - PyQt - 从另一个线程修改 GUI

linux - setitimer, SIGALRM & 多线程进程 (linux, c)

c - 如何在 Rust FFI 中访问 C 全局变量/常量?

c - 缺少应该存在的符号

c++ - speex解码出错

c - 带函数返回的地址运算符 "&"

c - 使用 C,如何访问与另一个 C 程序相同的内存块?

multithreading - 使用 OpenMP 的无用 printf 无法加速

java - 什么事件会使等待线程执行另一个线程已经运行的同步方法?