我正在運行此程序,我有多個線程。三個線程正在爲同一父進程生成信號。有四個處理線程用於處理由信號生成線程生成的信號。我有一個監視線程,它也接收信號和進程。但是,我有一個情況。我可以看到信號並不是平等分配的。我的意思是信號指向同一個過程。我有四個處理程序線程和一個監視線程等待信號。所以他們中的任何人都可以收到信號。我期待它被統一分發。但是,我可以看到,處理器線程接收到一整串信號。下一次整個信號突發由監視器線程處理。爲什麼它不統一。處理程序/監視器線程完成處理一個信號後,我添加了一個睡眠調用。所以只要處理器/監視器完成一個信號,它就應該有另一個機會來處理下一個信號。但是,輸出不顯示的情況下即使使用睡眠也不放棄CPU時間的線程
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <cstdio>
#include <stdlib.h>
#define NUM_SENDER_PROCESSES 3
#define NUM_HANDLER_PROCESSES 4
#define NUM_SIGNAL_REPORT 10
#define MAX_SIGNAL_COUNT 100000
using namespace std;
volatile int usrsig1_handler_count = 0;
int usrsig2_handler_count = 0;
int usrsig1_sender_count = 0;
int usrsig2_sender_count = 0;
int monitor_count = 0;
int usrsig1_monitor_count = 0;
int usrsig2_monitor_count = 0;
double time_1[10];
double time_2[10];
int lock_1 = 0;
int lock_2 = 0;
int lock_3 = 0;
int lock_4 = 0;
int lock_5 = 0;
double timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return (double)tp.tv_sec + tp.tv_usec/1000000.;
}
void sleepMs(double seconds) {
usleep((unsigned int)(seconds*1000000));
}
void *senderfunc(void *parm) {
srand(time(0));
while(true) {
int signal_id = rand()%2 + 1;
if(signal_id == 1) {
while(__sync_lock_test_and_set(&lock_3,1) != 0) {
}
usrsig1_sender_count++;
lock_3 = 0;
kill(getpid(), SIGUSR1);
} else {
while(__sync_lock_test_and_set(&lock_4,1) != 0) {
}
usrsig2_sender_count++;
lock_4 = 0;
kill(getpid(), SIGUSR2);
}
int r = rand()%10 + 1;
double s = (double)r/100;
sleepMs(s);
}
}
void *handlerfunc(void *parm)
{
int *index = (int *)parm;
sigset_t set;
sigemptyset(&set);
//cout << (*index) << endl;
if((*index) % 2 == 0) {
sigaddset(&set, SIGUSR1);
} else {
sigaddset(&set, SIGUSR2);
}
int sig;
while(true) {
sigwait(&set, &sig);
//cout << "Handler" << endl;
if (sig == SIGUSR1) {
while(__sync_lock_test_and_set(&lock_1,1) != 0) {
}
usrsig1_handler_count++;
lock_1 = 0;
} else if(sig == SIGUSR2) {
while(__sync_lock_test_and_set(&lock_2,1) != 0) {
}
usrsig2_handler_count++;
lock_2 = 0;
}
sleepMs(0.0001);
}
}
void *monitorfunc(void *parm) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
int sig;
while(true) {
sigwait(&set, &sig);
//cout << "Monitor" << endl;
if(sig == SIGUSR1) {
time_1[usrsig1_monitor_count] = timestamp();
usrsig1_monitor_count++;
} else if(sig == SIGUSR2) {
time_2[usrsig2_monitor_count] = timestamp();
usrsig2_monitor_count++;
}
monitor_count++;
//cout << monitor_count << endl;
if(monitor_count == NUM_SIGNAL_REPORT) {
double difference_1 = 0;
double difference_2 = 0;
if(usrsig1_monitor_count > 1) {
for(int i=0; i<usrsig1_monitor_count-1; i++) {
difference_1 = difference_1 + time_1[i+1] - time_1[i];
}
cout << "Interval SIGUSR1 = " << difference_1/(usrsig1_monitor_count-1)<< endl;
}
if(usrsig2_monitor_count > 1) {
for(int i=0; i<usrsig2_monitor_count-1; i++) {
difference_2 = difference_2 + time_2[i+1] - time_2[i];
}
cout << "Interval SIGUSR2 = " << difference_2/(usrsig2_monitor_count-1) << endl;
}
cout << "Count SIGUSR1 = " << usrsig1_sender_count << endl;
cout << "Count SIGUSR2 = " << usrsig2_sender_count << endl;
monitor_count = 0;
usrsig1_monitor_count = 0;
usrsig2_monitor_count = 0;
}
sleepMs(0.001);
}
}
int main(int argc, char **argv)
{
if(argc != 2) {
cout << "Required parameters missing. " << endl;
cout << "Option 1 = 1 which means run for 30 seconds" << endl;
cout << "Option 2 = 2 which means run until 100000 signals" << endl;
exit(0);
}
int option = atoi(argv[1]);
int i;
pthread_t handlers[NUM_HANDLER_PROCESSES];
pthread_t generators[NUM_SENDER_PROCESSES];
pthread_t monitor;
sigset_t set;
sigset_t oldset;
sigemptyset(&oldset);
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
pthread_sigmask(SIG_BLOCK, &set, &oldset);
int handler_mask[4] = {0,1,2,3};
//Initializing the handler threads
for(i=0; i<NUM_HANDLER_PROCESSES; i++) {
pthread_create(&handlers[i], NULL, handlerfunc, (void *)&handler_mask[i]);
}
pthread_create(&monitor, NULL, monitorfunc, NULL);
sleep(5);
for(i=0; i<NUM_SENDER_PROCESSES; i++) {
pthread_create(&generators[i], NULL, senderfunc, NULL);
}
if(option == 1) {
cout << "Option 1 " << endl;
//sleep(30);
while(true){
}
exit(0);
} else {
while(true) {
if((usrsig1_handler_count + usrsig2_handler_count) >= MAX_SIGNAL_COUNT) {
cout << "Count SIGUSR1 = " << usrsig1_handler_count << endl;
cout << "Count SIGUSR2 = " << usrsig2_handler_count << endl;
exit(0);
} else {
pthread_yield();
}
}
}
}
這裏是我的輸出
HandlerHandler
Handler
Handler
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Monitor
Handler
Handler
Handler
Handler
Handler
Handler
Handler
Handler
Handler
Handler
你可以看到顯示器的突發,隨後處理的爆裂。但是,在代碼中,一旦處理程序/監視器處理了一個信號並進入sigwait,我就添加了一個睡眠調用,以便將該轉換傳遞給下一個可用線程。但是,這沒有幫助。我猜這應該是統一的。但是,監視器仍然會爆炸並打印。即使在監視器中,當它已完成其信號作業後,它已經進入睡眠狀態
@ K-ballo。我沒有明白。當處理器/顯示器從sigwait中喚醒時,我只是在打印。由於我已經使用了睡眠,所以他們應該輪流醒來。我的意思是我在顯示器線程上使用了sigwait,它處理一個信號然後睡覺。與此同時,處理線程獲得CPU時間,從sigwait中喚醒並處理信號並進入睡眠狀態。所以他們應該輪流是不是? – user34790
有什麼辦法可以看到,即使我使用睡眠爲什麼同一個線程有機會使用sigwait解鎖信號並處理它? – user34790
你的問題是什麼?你想知道線程時間爲什麼沒有統一分佈? – user1708860