c - pthread_cond_signal 在调用线程退出之前未到达另一个线程

标签 c multithreading pthreads posix

我试图通过线程之间的同步(目前从 2 开始)来模拟上下文切换,以便每个线程充当一个进程,并且进程切换发生在每个 TIMESLICE 间隔(目前为 3 毫秒)。通过一次仅执行一个线程进行的线程切换运行得很好,但是当第一个线程退出但 pthread_cond_signal 时就会出现问题。调用线程退出前执行的操作不会唤醒 pthread_cond_wait另一个线程的。

这是 C 程序:

#include<stdio.h> //for printf
#include<pthread.h> //for threads, mutual exclusion, conditional wait and signalling
#include<time.h> //for accurate clock time
#include<limits.h> //for min-max limits of several data types
#include<inttypes.h> //for using uint64_t data type

#define bool int
#define true 1
#define false 0

#define TIMESLICE 3000000 //nanoseconds to define milliseconds
#define BILLION 1000000000L

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock_t = PTHREAD_MUTEX_INITIALIZER;
int numProcWait = 2;

void *threadFunction(void *arg) {
    int i;
    uint64_t diff=0;
    bool locked,unlockCheck=true; // locked for synchronizing the thread withing itself
    // unlock check for if the for loop exits without unlocking the mutex and without signalling the other thread   

    struct timespec start, end;
    pthread_cond_wait(&cond,&lock_t);
    pthread_mutex_lock(&lock);

    clock_gettime(CLOCK_MONOTONIC, &start);

    locked = true;
    for (i = 0; i < INT_MAX/2048; i++) {

        if(locked==false) {
            pthread_mutex_lock(&lock);
            printf("Lock acquired by Thread id: %lu\n",pthread_self());
            locked = true;
            diff = 0;
            clock_gettime(CLOCK_MONOTONIC, &start);
        }
        clock_gettime(CLOCK_MONOTONIC, &end);
        diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
        unlockCheck = true;

        if(diff > TIMESLICE) {

            if(i==INT_MAX-1)
                unlockCheck = false;

            if(numProcWait>1) {
                locked = false;     
                printf("Lock released by Thread id: %lu\n",pthread_self());
                printf("Diff Time: %" PRIu64 " ms\n\n",diff/1000000);

                pthread_mutex_unlock(&lock);
                printf("Unlocking from thread Successful! Thread ID: %lu\n\n",pthread_self());
                pthread_cond_signal(&cond);
                printf("Waiting Thread id: %lu\n\n",pthread_self());
                pthread_cond_wait(&cond,&lock_t);
                printf("Received Signal Successful! Thread ID: %lu\n\n",pthread_self());
            }
        }
    }
    //this condition would occur false on a very rare case
    if(unlockCheck) {
        printf("Lock released from out of the loop by Thread id: %lu\n\n",pthread_self());
        //this condition is executed but it doesn't wakes up the pthread_cond_wait function of the other thread.
        pthread_mutex_unlock(&lock);
        pthread_cond_signal(&cond);     
    }

    printf("EXITING THREAD: %lu\n\n",pthread_self());
    numProcWait--;
    printf("Number of processes waiting: %d\n\n",numProcWait);
    return NULL;
}

int main() {

    pthread_t tid[2];
    uint64_t diff;
    struct timespec start, end;

    clock_gettime(CLOCK_MONOTONIC, &start);

    pthread_create(&tid[0], NULL, threadFunction, NULL);
    pthread_create(&tid[1], NULL, threadFunction, NULL);

    sleep(1);
    pthread_cond_broadcast(&cond);

    pthread_join(tid[0], NULL);
    printf("Thread 1 EXITED. No. of Waiting Processes: %d\n",numProcWait);
    //pthread_cond_signal(&cond);   
    pthread_join(tid[1], NULL);
    printf("Thread 2 EXITED. No. of Waiting Processes: %d\n",numProcWait);
    clock_gettime(CLOCK_MONOTONIC, &end);
    diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;

    printf("Total Run Time: %" PRIu64 " ms\n",diff/1000000);
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);
}

最佳答案

您需要在调用条件等待和信号之前锁定互斥锁,如下所示。

等待:

pthread_mutex_lock(&lock_t);
pthread_cond_wait(&cond,&lock_t);
pthread_mutex_unlock(&lock_t);

信号:

pthread_mutex_lock(&lock_t);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock_t);

关于c - pthread_cond_signal 在调用线程退出之前未到达另一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40179553/

相关文章:

c - PIC24h portB寄存器随机变高

C++如何在银行账户转账时避免竞争条件

Java 线程安全 - 了解同步的需要

PHP + pthreads : Build one big object - parallel-processing

c - pthread_join() 导致段错误

c - 如何使用 c 使用 libpng 更改 png 图像的 rgb 值?

c - Windows逆向工程: find a specific Windows structure

C - 循环输入

java - 在java中同步两个线程

c++ - 使用两个线程和system()命令运行shell脚本: how to make sure that one shell script is started before another