天天看點

Java LockSupport.park()根據信号排程原理

1. 有兩個線程

一個線程等待信号,直到擷取信号之後再執行下面的代碼

一個線程向另一個線程發信号

jvm源碼位置

jdk7u/jdk7u/hotspot: 677234770800 src/os/linux/vm/os_linux.cpp

2. c語言實作

signal_wake_up.c

#include<stdio.h>
#include <unistd.h>
#include<pthread.h>
#include <signal.h>
#include<time.h>

pthread_t pt, pt2;

void print_date(){
    time_t time1;
    time(&time1);
    struct tm* t1 = localtime(&time1);
    char buf[50];
    strftime(buf, 50, "%Y-%m-%d %H:%M:%S", t1);
    printf("%s\n", buf);
}

void* thread_run(void* arg){
    sigset_t set;
    sigaddset(&set, SIGALRM);
    for (;;){
        int sig;
        // 等待信号被喚醒
        sigwait(&set, &sig);
        printf("up %d\n", sig);
        print_date();
    }
}

void* thread_run2(void* arg){
    while (1){
        sleep(3);
        // 發送信号給pt線程
        pthread_kill(pt, SIGALRM);
    }
}

void sighandle(int num){
    printf("num %d\n", num);
}

int main(){
   signal(SIGALRM, sighandle);

   int ret1 = pthread_create(&pt, NULL, thread_run, NULL);
   
   if (ret1 == -1){
       perror("pthread_create");
       _exit(0);
   }

   int ret2 = pthread_create(&pt2, NULL, thread_run2, NULL);
   if (ret2 == -1){
       perror("pthread_create");
       _exit(0);
   }

   pthread_join(pt, NULL);
   pthread_join(pt2, NULL);
   return 0;
}
           

編譯

gcc signal_wake_up.c -o sig_wake_up -lpthread
           

執行結果,

Java LockSupport.park()根據信号排程原理

 pt線程每3秒被喚醒一次

3.參考資料

jvm源碼分析之LockSupport_lzf的部落格-CSDN部落格