Мне нужно написать программу для класса, которая создает 8 потоков. 4 производителя и 4 потребителя. Производителям необходимо зацикливать и произвольно отправлять SIGUSR1 или SIGUSR2 ко всем потребительским потокам. Только 2 должны зарегистрироваться, если они получили SIGUSR1 и другие 2 регистра SIGUSR2.Создаются нити, затем все выходят до критической области
Когда я пытаюсь запустить его, все потоки создаются, «готовый продукт» печатается всеми 4 потоками производителей, «ожидание 1» печатается обоими потоками, но «ожидание 2» печатается 3 раза, после чего все потоки выходят , В конце отладки говорится, что процесс завершается нормально.
Мне нужно использовать семафоры для управления критическими областями. Любая помощь будет большой.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>
#define NP 4
#define NC1 2
#define NC2 2
#define CNT 10
void handler1(int signum);
void handler2(int signum);
typedef struct {
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con;
sem_t prod;
} sbuf_t;
sbuf_t buff;
void *producer() {
printf("prod ready \n");
int s;
while(1){
sem_wait(&buff.prod);
s=rand()%2;
if(s==1){
buff.sent++;
kill(0,SIGUSR1);
}
else if(s==2){
buff.sent++;
kill(0,SIGUSR2);
}sem_post(&buff.prod);
}
}
void *consumer1() {
signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1){
}
}
void *consumer2() {
signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1){
}
}
void handler1(int signum){
if(signum==SIGUSR1){
sem_wait(&buff.con);
printf("Caught 1\n");
buff.received++;
buff.SIG1++;
sem_post(&buff.con);
}
}
void handler2(int signum){
if(signum==SIGUSR2){
sem_wait(&buff.con);
printf("caught 2 \n");
buff.received++;
buff.SIG2++;
sem_post(&buff.con);
}
}
void main(){
pthread_t threads[9];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con, 0, 0);
sem_init(&buff.prod, 0, 0);
for (index = 0; index < NP; index++) {
pthread_create(&threads[index], NULL, producer,NULL);
}
for (index = 0;index < NC1;index++) {
pthread_create(&threads[index+4], NULL, consumer1,NULL);
}
for (index = 0;index < NC2;index++) {
pthread_create(&threads[index+6], NULL, consumer2,NULL);
}
}
для удобства чтения и понимания: 1) последовательно отступать код. Отступ после каждой открывающей скобки '{'. unindent перед каждой закрывающей скобкой '}'. Предложите использовать 4 пробела для каждого уровня отступов, так как это видно даже с переменной шириной шрифта. Никогда не используйте вкладки для отступов, так как каждый текстовый процессор/редактор имеет ширину табуляции/ширину закладки, установленную по-разному. 2) отдельные блоки кода (для if, else, while, do ... while, switch, case, default) через пустую строку. – user3629249
Независимо от того, что Visual Studio позволит вам уйти; функция main() 'имеет только две действительные сигнатуры:' int main (void) 'и' int main (int argc, char * argv []) 'I.E. все они имеют тип возврата 'int'. – user3629249
Когда код выполняет сравнение между литералом и чем-либо еще для равенства, всегда помещайте литерал слева, поэтому любая ошибка ключевого слова, такая как использование '=', а не '==', будет улавливаться компилятором, а не тратить часы и часы и получение седых волос над простой ошибкой клавиш. – user3629249