在循环中创建线程
Thread creation in loop
我正在尝试执行多写入器程序,其中每个写入器线程一个一个地获取队列的锁,然后多个 reader 读取它。以下代码对第一个作者工作正常,但它没有为第二个作者自己的病房提供所需的输出,实际上在第一次迭代后没有调用作者线程函数。请帮助..
for(i = 0; i < wno; i++)
{
fflush(stdin);
ret = pthread_create(&writter[i], NULL, write_to_queue, NULL);
if( ret != 0)
{
printf("Could not create Thread \n");
break;
}
else
{
sleep(10);
printf("Value of ret %d\n", ret);
for(j = 0; j < rno; j++)
{
pthread_create(&reader[t], NULL, read_from_queue, NULL);
//sleep(2);
t++;
}
sleep(1);
}
void *write_to_queue()
{
int ch;
pthread_mutex_lock(&lock);
while(ch != 0)
{
fflush(stdin);
printf("Choose one of the following to proceed\nPress 1 to EnQueue\nPress 2 to DeQueue\nPress 0 to Exit\n");
scanf("%d", &ch);
getchar();
switch(ch)
{
case 0 : ch = 0; break;
case 1 : EnQueue(); break;
case 2 : DeQueue(); break;
default : printf("Please Enter a valid Choice\n"); break;
}
}
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
reader 个线程工作正常。
lock
在进入循环前获取,退出循环后才释放
如果您希望线程在每次迭代中竞争,请将获取和释放调用移动到循环内。请注意,您的代码因读取 ch
未初始化而具有未定义的行为。下面的代码解决了这个问题。
int ch = -1; // Initialize!
while (ch != 0) {
pthread_mutex_lock(&lock);
printf("%s",
"Choose one of the following to proceed\n"
"Press 1 to EnQueue\n"
"Press 2 to DeQueue\n"
"Press 0 to Exit\n");
scanf("%d", &ch);
getchar();
switch(ch) {
case 0 : ch = 0; break;
case 1 : EnQueue(); break;
case 2 : DeQueue(); break;
default : printf("Please Enter a valid Choice\n"); break;
}
pthread_mutex_unlock(&lock);
}
作为多线程编程设计的问题,你应该避免"fat lock syndrome"。 胖锁 是一种在线程代码的很大一部分上序列化执行的锁,它实际上消除了程序中的任何并行执行。
要实现并行性,应使用更精细的方法来保护关键部分。这意味着锁的获取和释放仅与需要它的代码部分隔离。这通常意味着对特定共享数据结构的操作,在您的情况下,它将是 EnQueue
和 DeQueue
操作。
您的特定程序似乎 I/O 很重。不幸的是,如果您想要一致的 I/O 行为,则必须将访问 stdin
和 stdout
视为关键部分。但是,您可以考虑创建一个单独的 I/O 线程,它可以在不需要锁的情况下与 stdin
和 stdout
交互。选择可以放在工作队列上,工作线程可以在工作队列上等待执行工作。当每个线程处理请求的工作时,它可以根据需要执行粒度锁定以完成工作。
我正在尝试执行多写入器程序,其中每个写入器线程一个一个地获取队列的锁,然后多个 reader 读取它。以下代码对第一个作者工作正常,但它没有为第二个作者自己的病房提供所需的输出,实际上在第一次迭代后没有调用作者线程函数。请帮助..
for(i = 0; i < wno; i++)
{
fflush(stdin);
ret = pthread_create(&writter[i], NULL, write_to_queue, NULL);
if( ret != 0)
{
printf("Could not create Thread \n");
break;
}
else
{
sleep(10);
printf("Value of ret %d\n", ret);
for(j = 0; j < rno; j++)
{
pthread_create(&reader[t], NULL, read_from_queue, NULL);
//sleep(2);
t++;
}
sleep(1);
}
void *write_to_queue()
{
int ch;
pthread_mutex_lock(&lock);
while(ch != 0)
{
fflush(stdin);
printf("Choose one of the following to proceed\nPress 1 to EnQueue\nPress 2 to DeQueue\nPress 0 to Exit\n");
scanf("%d", &ch);
getchar();
switch(ch)
{
case 0 : ch = 0; break;
case 1 : EnQueue(); break;
case 2 : DeQueue(); break;
default : printf("Please Enter a valid Choice\n"); break;
}
}
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
reader 个线程工作正常。
lock
在进入循环前获取,退出循环后才释放
如果您希望线程在每次迭代中竞争,请将获取和释放调用移动到循环内。请注意,您的代码因读取 ch
未初始化而具有未定义的行为。下面的代码解决了这个问题。
int ch = -1; // Initialize!
while (ch != 0) {
pthread_mutex_lock(&lock);
printf("%s",
"Choose one of the following to proceed\n"
"Press 1 to EnQueue\n"
"Press 2 to DeQueue\n"
"Press 0 to Exit\n");
scanf("%d", &ch);
getchar();
switch(ch) {
case 0 : ch = 0; break;
case 1 : EnQueue(); break;
case 2 : DeQueue(); break;
default : printf("Please Enter a valid Choice\n"); break;
}
pthread_mutex_unlock(&lock);
}
作为多线程编程设计的问题,你应该避免"fat lock syndrome"。 胖锁 是一种在线程代码的很大一部分上序列化执行的锁,它实际上消除了程序中的任何并行执行。
要实现并行性,应使用更精细的方法来保护关键部分。这意味着锁的获取和释放仅与需要它的代码部分隔离。这通常意味着对特定共享数据结构的操作,在您的情况下,它将是 EnQueue
和 DeQueue
操作。
您的特定程序似乎 I/O 很重。不幸的是,如果您想要一致的 I/O 行为,则必须将访问 stdin
和 stdout
视为关键部分。但是,您可以考虑创建一个单独的 I/O 线程,它可以在不需要锁的情况下与 stdin
和 stdout
交互。选择可以放在工作队列上,工作线程可以在工作队列上等待执行工作。当每个线程处理请求的工作时,它可以根据需要执行粒度锁定以完成工作。