【发布时间】:2016-11-05 22:40:28
【问题描述】:
我需要为创建 8 个线程的类编写一个程序。 4个生产者,4个消费者。生产者需要循环,并随机发送 SIGUSR1 或 SIGUSR2 到所有消费者线程。如果他们收到了 SIGUSR1,则只有 2 个应该注册,另外 2 个注册 SIGUSR2。
当我尝试运行它时,所有线程都已创建,所有 4 个生产者线程都打印了“prod ready”,两个线程都打印了“waiting 1”,但是“waiting 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) 一致地缩进代码。在每个左大括号“{”后缩进。在每个右大括号 '}' 之前不缩进。建议为每个缩进级别使用 4 个空格,因为即使使用可变宽度字体也是如此。切勿使用制表符进行缩进,因为每个文字处理器/编辑器的制表位/制表宽度设置不同。 2) 通过空行分隔代码块(for、if、else、while、do...while、switch、case、default)。
-
不管 Visual Studio 会让你摆脱什么;
main()函数只有两个有效签名:int main( void )和int main( int argc, char *argv[] )I.E。它们的返回类型均为int。 -
当代码在一个字面量和其他任何东西之间进行比较是否相等时,总是把字面量放在左边,所以任何按键错误,比如使用
=而不是==都会被编译器,而不是您花费数小时和数小时,因为一个简单的按键错误而变得白发。 -
有一长串函数不能在信号处理程序中使用。其中一个被禁止的函数是
printf(),因为它“可能”导致嵌套的信号事件,这将使程序崩溃。函数sem_wait()也存在类似的考虑建议阅读可以调用函数的手册页信号(7) -
在 linux、system V 和 BSD 中,强烈建议不要使用函数:
signal(),因为它的不可靠性和不一致的实现。强烈建议使用:sigaction()。
标签: c multithreading signals signal-processing semaphore