简体   繁体   English

严格使用 mutex_lock 和 mutex_unlock 在 2 个线程之间切换作为学术练习

[英]Strictly using mutex_lock & mutex_unlock to switch between 2 threads as an academic exercise

当前互斥逻辑

Hello everyone,大家好,

I am stuck with a mutex logic issue.我遇到了互斥逻辑问题。 I am using mutexes to switch between/synchronize two threads.我正在使用互斥锁在两个线程之间切换/同步。

Thread one is required to read part of a file and then update a global var.线程一需要读取文件的一部分,然后更新全局变量。 It then switches to thread two which does a task and then returns to thread one to continue reading the next part of the file.然后它切换到执行任务的线程二,然后返回到线程一继续读取文件的下一部分。

In main I am using sleep to force the first thread to execute.在 main 中,我使用 sleep 来强制执行第一个线程。 So far so good, After entering the first thread I update the variable in the critical section and the remain stuck inside thread 1 not switching to thread 2. Thread 2 is only entered after the thread 1 has run twice and we are at the second integer in the input file.到目前为止一切顺利,进入第一个线程后,我更新了临界区中的变量,并且仍然卡在线程 1 内,没有切换到线程 2。线程 2 仅在线程 1 运行两次后进入,我们在第二个 integer在输入文件中。 Any advice on where my logic is wrong here would be appreciated.任何关于我的逻辑在哪里出错的建议都将不胜感激。 Thank you.谢谢你。

Output: Output:

in thead 1
inside t1 while loop
inside critical section
Thread 1 updated GlobalVar to: 1 
inside t1 while loop
inside critical section
Thread 1 updated GlobalVar to: 2 
Thread 2:
//struct to pass file to thread 2
struct THEAD_TWO_DATA{
    FILE *outputFile;
}; 

pthread_mutex_t m1_lock = PTHREAD_MUTEX_INITIALIZER; // declaring mutex
pthread_mutex_t m2_lock = PTHREAD_MUTEX_INITIALIZER; // declaring mutex
int globalValue = 0;
int count = 0;

void* ThreadOne(void *param){
    printf("in thead 1\n");
    int value1;
    FILE *inputFile;  
    inputFile = fopen("hw3.in", "r");
    while (!feof (inputFile)){
        printf("inside t1 while loop\n");
        printf("inside critical section\n");
        pthread_mutex_lock(&m2_lock);
        fscanf (inputFile, "%d", &value1);
        globalValue = value1;
        printf("Thread 1 updated GlobalVar to: %d \n",globalValue);
        pthread_mutex_lock(&m1_lock);
        pthread_mutex_unlock(&m2_lock);
        count++;
    }
    printf("out of thread one loop\n");
    fclose (inputFile);
    pthread_exit(NULL);
}

void* ThreadTwo(void *received_struct){ 
    struct THEAD_TWO_DATA *struct_ptr = (struct THEAD_TWO_DATA*) received_struct;
    printf("Thread 2:\n");
    for (int i=0; i < count; i++){
        pthread_mutex_lock(&m1_lock);
        int r = globalValue % 2;
        if (r == 0){ // even
            fprintf(struct_ptr->outputFile, "%d\n", globalValue);
            fprintf(struct_ptr->outputFile, "%d\n", globalValue);
            printf("twice becase it is even\n");
            pthread_mutex_lock(&m2_lock);
        }
        else{
            fprintf(struct_ptr->outputFile, "%d\n", globalValue);
            printf("Once because it is odd\n");
            pthread_mutex_lock(&m2_lock);
        }
        pthread_mutex_unlock(&m1_lock);
    }
    pthread_exit(NULL);
}

int main(){
    pthread_t th[2];
    pthread_mutex_init(&m1_lock, NULL);
    pthread_mutex_init(&m2_lock, NULL);

    pthread_create(&th[0], NULL, ThreadOne, NULL);
    sleep(1);
    pthread_create(&th[1], NULL, ThreadTwo, &my_Struct);

    pthread_join(th[0], NULL);
    pthread_join(th[1], NULL);

    pthread_mutex_destroy(&m1_lock);
    pthread_mutex_destroy(&m2_lock);

    return 0;
}

Let main() initialize normal "fast" mutexes with mutex 2 pre-locked.让 main() 使用预锁定的互斥锁 2 初始化普通的“快速”互斥锁。 Then start both threads, start order doesn't matter and there's no reason to sleep.然后启动两个线程,启动顺序无关紧要,没有理由睡觉。

Each thread waits for its own mutex, does its thing, then unlocks the OTHER mutex and goes back to waiting for its own mutex again.每个线程等待它自己的互斥体,做它自己的事情,然后解锁另一个互斥体并再次返回等待它自己的互斥体。

Since mutex 2 is initially locked, it will wait for thread 1 to unlock it.由于互斥锁 2 最初被锁定,它将等待线程 1 解锁它。 Then thread 1 will wait for thread 2 to unlock it, etc.然后线程 1 将等待线程 2 解锁它,等等。

When thread 1 finally reads EOF it sets a kamikaze flag for thread 2 and unlocks it one final time, then exits.当线程 1 最终读取 EOF 时,它为线程 2 设置一个 kamikaze 标志并最后一次解锁它,然后退出。 Thread 2 sees the flag and also exits.线程 2 看到标志并且也退出。

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

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