我需要为创建8个线程的类编写一个程序。 4个生产者,4个消费者。生产者需要循环,并随机将SIGUSR1或SIGUSR2发送给所有消费者线程。如果他们已经收到SIGUSR1而另外2个寄存器SIGUSR2,则只有2个应该注册。
当我尝试运行它时,所有线程都被创建,所有4个生产者线程都会打印“prod ready”,两个线程都会打印“等待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);
}
}
答案 0 :(得分:0)
在main()
函数中,正在创建线程
然后main()
退出。
当main()退出时,所有线程也会退出。
建议阅读以下功能:pthread_exit()
和pthread_join()
注意:以下在处理信号和处理信号量时出错,但会演示使用pthread_join()和pthread_exit()
#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
#define MAX_THREADS (9)
void handler1(int signum);
void handler2(int signum);
struct sbuf_t
{
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con1;
sem_t con2;
sem_t prod;
};
typedef struct sbuf_t myData;
myData buff;
void *producer( void *dummy )
{
(void)dummy;
printf("prod ready \n");
int s;
while(1)
{
sem_wait(&buff.prod);
s=rand()%2;
if( !s )
{
buff.sent++;
kill( 0, SIGUSR1 );
}
else // if( s )
{
buff.sent++;
kill( 0, SIGUSR2 );
}
//sem_post(&buff.prod);
}
pthread_exit( NULL );
} // end thread: producer
void *consumer1( void *dummy )
{
(void)dummy;
//signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1)
{
sem_wait( &buff.con1 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer1
void *consumer2( void *dummy )
{
(void)dummy;
//signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1)
{
sem_wait( &buff.con2 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer2
void handler(int signum)
{
sem_post(&buff.prod);
if(signum==SIGUSR1)
{
//sem_wait(&buff.con);
puts("Caught 1");
buff.received++;
buff.SIG1++;
sem_post(&buff.con1);
}
else if(signum==SIGUSR2)
{
//sem_wait(&buff.con);
puts("caught 2");
buff.received++;
buff.SIG2++;
sem_post(&buff.con2);
}
} // end signal handler: handler2
int main( void )
{
pthread_t threads[ MAX_THREADS ];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con1, 0, 0);
sem_init(&buff.con2, 0, 0);
sem_init(&buff.prod, 0, 0);
signal(SIGUSR2, handler);
signal(SIGUSR1, handler);
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);
}
for( size_t x=0; x<MAX_THREADS; x++ )
{
pthread_join( threads[x], NULL );
}
} // end function: main
但是,处理线程信号的方法不会像处理那样使用kill()
。
而代码应该使用类似于::
的函数int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_signal(pthread_cond_t *cond)
发出信号的线程应该在pthread_cond_wait()
调用时阻塞,直到另一个线程使用pthread_cond_signal()
发送信号,并使用相同的条件变量。
考虑到与传递给进程的信号的类比,这有点不同,因为已发出信号的线程已经暂停其执行等待信号,这与一个简单地被中断并继续进行的进程不同。
答案 1 :(得分:-1)
例如,您在消费者面前创建生产者。同样在您的制作人中,您使用随机数生成器来确定您是否发出USR1或USR2。你的描述给人的印象是你想要的两个(相对于一些随机混合总共4个),这就是我看到代码为你做的。