创建线程,然后在关键区域之前全部退出

时间:2016-11-05 22:40:28

标签: c multithreading signals signal-processing semaphore

我需要为创建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);
        }
}

2 个答案:

答案 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个),这就是我看到代码为你做的。