简体   繁体   English

具有多线程的printf()

[英]printf() with multi-threading

I don't understanding the behavior of printf() here. 我在这里不了解printf()的行为。 If I lock the whole function, then the print out would be fine. 如果我锁定整个功能,那么打印输出就可以了。 But, if I modified the code so that it only lock the code has data dependency, one thread never gets ended? 但是,如果我修改了代码,使其仅锁定具有数据依赖性的代码,那么一个线程永远不会结束? Here's the code: 这是代码:

queue_lock is the problem. 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);
}

Sample output: 样本输出:

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

Output if to lock the whole thing: 输出是否锁定整个东西:

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

I have trimmed down a sample app, which occasionally behaves the same as your posted problem. 我整理了一个示例应用程序,该应用程序的行为有时与您发布的问题相同。

To recreate it, I 'forgot' to join on thread 2. 要重新创建它,我“忘了”加入线程2。
Can you make sure you are joining all your threads, and potentially post the block that is calling the threads? 您是否可以确保加入所有线程,并可能发布调用线程的块?

Based on your comment, I think this is the most likely. 根据您的评论,我认为这很有可能。 My application exhibits the same behavior, when prof2 finishes before prof1. 当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;

}

And I get this output, either success when prof2 finishes first: 我得到以下输出,或者当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

Or when prof1 finishes first ( I changed the rand values to make the other thread first, or you can swap the joins. ): 或者,当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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM