POSIX信号量与运行线程的相关进程

时间:2014-05-04 02:34:20

标签: linux pthreads posix mutex semaphore

我有一个以复杂的方式实现生产者消费者问题的任务(可能是为了测试我的理解)。父进程应该设置共享内存。应该初始化未命名的信号量(用于空计数和填充计数),并且应该初始化互斥锁。然后创建两个子进程,生成器子进程和消费者子进程。每个子进程都应该创建一个应该完成这项工作的新线程。

PS:我已经读过,信号量应保存在共享内存中,因为它们将由不同的进程共享。

请提供一些提示或建议更改。

到目前为止,我已经这样做了:

struct shmarea 
{
unsigned short int read;
unsigned short int max_size;
char scratch[3][50];
unsigned short int write;
sem_t sem1;// Empty slot semaphore
sem_t sem2;// Filled slot Semaphore
}; 

void *thread_read(void* args);
void *thread_write(void *args);

pthread_mutex_t work_mutex;

struct shmarea *shma;

int main()
{
int fork_value,i=0,shmid;
printf("Parent process id is %d\n\n",getpid());
int res1,res2;
key_t key;
char *path = "/tmp";
int id = 'S';

key = ftok(path, id);
shmid =  shmget(key,getpagesize(),IPC_CREAT|0666);

printf("Parent:Shared Memory id = %d\n",id);
shma = shmat(shmid,0,0);    

shma->read = 0;
shma->max_size = 3;
shma->write = 0; 

pthread_t a_thread;
pthread_t b_thread;

void *thread_result1,*thread_result2;

res1 = sem_init(&(shma->sem1),1,3);//Initializing empty slot sempahore
res2 = sem_init(&(shma->sem2),1,0);//Initializing filled slot sempahore

res1 = pthread_mutex_init(&work_mutex,NULL);

while(i<2)
{
    fork_value = fork();
    if(fork_value > 0)
    {
        i++;
    }
    if(fork_value == 0)
    {
        if(i==0)
        {           
            printf("***0***\n");
            //sem_t sem1temp = shma->sem1;
            char ch;int res;
            res= pthread_create(&a_thread,NULL,thread_write,NULL);
        }
        if(i==1)
        {
            printf("***1***\n");        
            //sem_t sem2temp = shma->sem2;      
            int res;
            char ch;
            res= pthread_create(&b_thread,NULL,thread_read,NULL);
        }
    }
}
int wait_V,status;
res1 = pthread_join(a_thread,&thread_result1);
res2 = pthread_join(b_thread,&thread_result2);
}

void *thread_read(void *args)
{   
    while(1)
    {
        sem_wait(&(shma->sem2));
        pthread_mutex_lock(&work_mutex);
        printf("The buf read from consumer:%s\n",shma->scratch[shma->read]);
        shma->read = (shma->read+1)%shma->max_size;             
        pthread_mutex_unlock(&work_mutex);
        sem_post(&(shma->sem1));
    }
} 

void *thread_write(void *args)
{
    char buf[50];
    while(1)
    {
        sem_wait(&(shma->sem1));    
        pthread_mutex_lock(&work_mutex);
        read(STDIN_FILENO,buf,sizeof(buf)); 
        strcpy(shma->scratch[shma->write],buf);
        shma->write = (shma->write+1)%shma->max_size;               
        pthread_mutex_unlock(&work_mutex);
        sem_post(&(shma->sem2));
    }
} 

1 个答案:

答案 0 :(得分:1)

(1)到目前为止,你最大的问题是你已经设法写了一个叉炸弹。因为你没有退出fork循环中的任何一个子节点,所以每个子节点都会通过并循环并创建自己的子节点,直到崩溃或使系统关闭。你想要更像这样的东西:

while(i < 2)
{
    fork_value = fork();

    if(fork_value > 0)
        i++;

    if(fork_value == 0)
    {
        if(i==0)
        {
            printf("0 child is pid %d\n", getpid());

            int res;
            res = pthread_create(&a_thread,NULL,thread_write,NULL);
            res = pthread_join(a_thread,&thread_result1);
            exit(0);
        }

        if(i==1)
        {
            printf("1 child is pid %d\n", getpid());

            int res;
            res = pthread_create(&b_thread,NULL,thread_read,NULL);
            res = pthread_join(b_thread,&thread_result2);
            exit(0);
        }
    }
}

for (i = 0; i < 2; ++i)
    wait(NULL);

注意你忽略的孩子的wait

(2)始终检查您的退货代码。它们就像安全带,有点拖累但是当你崩溃时非常有帮助。 (是的,我没有在这里听取我的意见,但你应该这样做。)

(3)这些名字很糟糕。

unsigned short int read;
unsigned short int write;

在系统调用后远离命名变量。这令人困惑,只是在寻找麻烦。

(4)术语明智,与这些共同祖先的过程是相关的。父级可以打开共享内存和其他资源,并将其传递给子级。例如,不相关的过程将是从不同终端发起的多个程序实例。他们可以共享资源,但不能以分叉流程的“继承”方式共享资源。

现在已经很晚了,并没有到处看看你正在做什么线程等等,但这应该让你开始。