gpt4 book ai didi

linux - 具有运行线程的相关进程的 POSIX 信号量

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:58:16 26 4
gpt4 key购买 nike

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

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) 到目前为止,您最大的问题是您设法编写了一个 fork 炸弹。因为你不退出 fork 循环中的任何一个 child ,所以每个 child 都会失败并循环并创建自己的 child ,直到你崩溃或使系统崩溃。你想要更像这样的东西:

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);

注意您忽略的 child 的 wait

(2) 始终检查您的返回码。它们就像安全带,有点拖累,但在您撞车时非常有用。 (是的,我在这里没有采纳我的建议,但你应该采纳。)

(3) 这些名字很糟糕。

unsigned short int read;
unsigned short int write;

避免在系统调用后命名变量。这令人困惑,只是自找麻烦。

(4) 就术语而言,具有共同祖先的进程是相关的,例如这些。 parent 可以打开共享内存和其他资源并将其传递给 child 。例如,不相关的进程可能是从不同终端启动的多个程序实例。它们可以共享资源,但不能像 fork 进程那样“继承”。

已经很晚了,没有时间查看您正在使用线程等做什么,但这应该让您开始。

关于linux - 具有运行线程的相关进程的 POSIX 信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23451976/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com