Estoy ejecutando este programa donde tengo varios hilos. Tres hilos generan señales para el mismo proceso principal. Hay cuatro hilos de manipulador para manejar las señales generadas por los hilos de generación de señal. Tengo un hilo de monitoreo que también recibe las señales y los procesos de acuerdo. Sin embargo, tengo una situación. Puedo ver que las señales no están divididas por igual. Quiero decir que las señales están dirigidas al mismo proceso. Tengo cuatro subprocesos de controlador y un subproceso de monitoreo esperando la señal. Entonces cualquiera de ellos puede recibir la señal. Esperaba que se distribuyera de manera uniforme. Sin embargo, pude ver que en el momento se reciben una ráfaga completa de señales por los hilos del manejador. La próxima vez toda la ráfaga de señales es manejada por el hilo del monitor. Por qué no es uniforme He agregado una llamada de suspensión después de que los hilos del controlador/monitor completen el manejo de una señal. Entonces, tan pronto como el controlador/monitor complete una señal, debería haber dado la otra oportunidad para manejar la siguiente señal. Sin embargo, la salida no muestra el casoHacer que los hilos tengan el mismo número de timeslices
#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();
}
}
}
}
Aquí está mi salida
HandlerHandler
Handler
Handler
Monitor
Monitor
... whole bunch of Monitor messages
Monitor
Monitor
Handler
Handler
... whole bunch of Handler messages
Handler
Handler
Se puede ver la explosión de la pantalla seguido de explosión de manipulador. Sin embargo, en el código una vez que un manejador/monitor maneja una señal y va para sigwait, he agregado una llamada de espera para que el giro pase al siguiente hilo disponible. Sin embargo, esto no está ayudando. Esto debería haberlo hecho uniforme, supongo. Sin embargo, aún el monitor se rompe e imprime. Aunque en el monitor he dormido después de haber terminado su trabajo para una señal
Si desea que la salida se entremezcle, debe usar semáforos o señales. –
@Joachim No lo entendí, ¿a qué te refieres? – user34790
Ver p. ['pthread_cond_init'] (http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_init.html). –