尝试使用线程在 C 中按顺序打印数字
Trying to print numbers sequentially in C using threads
我正在尝试学习线程和锁定,并编写了一个程序来使用两个线程按顺序打印数字,每个线程分别打印偶数和奇数。但似乎已经进入了僵局。有人可以告诉我我做错了什么吗?
/*
threads printing even odd number without shared variable
*/
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t even = PTHREAD_COND_INITIALIZER;
pthread_cond_t odd = PTHREAD_COND_INITIALIZER;
void print_even()
{
int i = 0;
do {
pthread_mutex_lock(&mux);
pthread_cond_wait(&odd, &mux);
i+=2;
printf("%d ", i);
pthread_cond_signal(&even);
pthread_mutex_unlock(&mux);
} while (i<100);
}
void print_odd()
{
int i = 1;
do {
pthread_mutex_lock(&mux);
pthread_cond_wait(&even, &mux);
i+=2;
printf("%d ", i);
pthread_cond_signal(&odd);
pthread_mutex_unlock(&mux);
} while (i<100);
}
int main()
{
pthread_t podd, peven;
pthread_mutex_init(&mux, NULL);
printf("The values are:\n");
pthread_create(&podd, NULL, (void *)&print_odd, NULL);
pthread_create(&peven, NULL, (void *)&print_even, NULL);
pthread_mutex_lock(&mux);
pthread_cond_signal(&even);
pthread_mutex_unlock(&mux);
pthread_join(podd, NULL);
pthread_join(peven, NULL);
printf("\ndone\n");
return 0;
}
如@user3386109 所述,主程序发送的信号太早了(在 print_odd 线程准备好之前),因此丢失,导致两个线程都死锁。将很快编辑程序和 post 代码。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t even_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t odd_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t even = PTHREAD_COND_INITIALIZER;
pthread_cond_t odd = PTHREAD_COND_INITIALIZER;
pthread_cond_t ready = PTHREAD_COND_INITIALIZER; /* to signal main that the
threads are created */
void print_even ()
{
pthread_mutex_lock (&even_mux);
pthread_mutex_lock (&main_mux);
pthread_cond_signal (&ready);
pthread_mutex_unlock (&main_mux);
int i = 0;
do {
pthread_cond_wait (&even, &even_mux);
i += 2;
printf ("%d ", i);
pthread_mutex_lock (&odd_mux);
pthread_cond_signal (&odd);
pthread_mutex_unlock (&odd_mux);
} while (i < 100);
pthread_mutex_unlock (&even_mux);
}
void print_odd ()
{
pthread_mutex_lock (&odd_mux);
pthread_mutex_lock (&main_mux);
pthread_cond_signal (&ready);
pthread_mutex_unlock (&main_mux);
int i = 1;
do {
pthread_cond_wait (&odd, &odd_mux);
i += 2;
printf ("%d ", i);
pthread_mutex_lock (&even_mux);
pthread_cond_signal (&even);
pthread_mutex_unlock (&even_mux);
} while (i < 100);
pthread_mutex_unlock (&odd_mux);
}
int main (void)
{
pthread_t podd, peven;
pthread_mutex_init (&odd_mux, NULL);
pthread_mutex_init (&even_mux, NULL);
pthread_mutex_init (&main_mux, NULL);
printf ("The values are:\n");
pthread_mutex_lock (&main_mux);
if (pthread_create (&podd, NULL, (void *) &print_odd, NULL) != 0) {
exit (1);
}
pthread_cond_wait (&ready, &main_mux);
if (pthread_create (&peven, NULL, (void *) &print_even, NULL) != 0) {
exit (1);
}
pthread_cond_wait (&ready, &main_mux);
pthread_mutex_unlock (&main_mux);
pthread_mutex_lock (&even_mux);
pthread_cond_signal (&even);
pthread_mutex_unlock (&even_mux);
pthread_join (podd, NULL);
pthread_join (peven, NULL);
printf ("\ndone\n");
return 0;
}
您使用条件变量的方式存在缺陷。对你来说,他们本身似乎是一个传达需要做某事的渠道。相反,使用它们作为指标来检查当前状态是否需要做任何事情。
伪代码:
mutex m
condition_var odd
condition_var even
integer i
function handle odd numbers:
lock(m)
while true:
if i is odd:
print i
increment i
signal even
wait odd
function handle even numbers:
lock(m)
while true:
if i is even:
print i
increment i
signal odd
wait even
main:
i = 0
start thread to handle odd numbers
start thread to handle even numbers
如您所见,在等待之前,线程会检查共享计数器是奇数还是偶数,然后相应地执行操作。但是,它不需要事件,特别是在 main() 中启动线程和发出事件信号之间没有竞争条件。
免责声明:条件变量应该这样使用,但绝不是好的MT编程!请务必阅读并理解针对您问题的评论!
我正在尝试学习线程和锁定,并编写了一个程序来使用两个线程按顺序打印数字,每个线程分别打印偶数和奇数。但似乎已经进入了僵局。有人可以告诉我我做错了什么吗?
/*
threads printing even odd number without shared variable
*/
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t even = PTHREAD_COND_INITIALIZER;
pthread_cond_t odd = PTHREAD_COND_INITIALIZER;
void print_even()
{
int i = 0;
do {
pthread_mutex_lock(&mux);
pthread_cond_wait(&odd, &mux);
i+=2;
printf("%d ", i);
pthread_cond_signal(&even);
pthread_mutex_unlock(&mux);
} while (i<100);
}
void print_odd()
{
int i = 1;
do {
pthread_mutex_lock(&mux);
pthread_cond_wait(&even, &mux);
i+=2;
printf("%d ", i);
pthread_cond_signal(&odd);
pthread_mutex_unlock(&mux);
} while (i<100);
}
int main()
{
pthread_t podd, peven;
pthread_mutex_init(&mux, NULL);
printf("The values are:\n");
pthread_create(&podd, NULL, (void *)&print_odd, NULL);
pthread_create(&peven, NULL, (void *)&print_even, NULL);
pthread_mutex_lock(&mux);
pthread_cond_signal(&even);
pthread_mutex_unlock(&mux);
pthread_join(podd, NULL);
pthread_join(peven, NULL);
printf("\ndone\n");
return 0;
}
如@user3386109 所述,主程序发送的信号太早了(在 print_odd 线程准备好之前),因此丢失,导致两个线程都死锁。将很快编辑程序和 post 代码。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t even_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t odd_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t even = PTHREAD_COND_INITIALIZER;
pthread_cond_t odd = PTHREAD_COND_INITIALIZER;
pthread_cond_t ready = PTHREAD_COND_INITIALIZER; /* to signal main that the
threads are created */
void print_even ()
{
pthread_mutex_lock (&even_mux);
pthread_mutex_lock (&main_mux);
pthread_cond_signal (&ready);
pthread_mutex_unlock (&main_mux);
int i = 0;
do {
pthread_cond_wait (&even, &even_mux);
i += 2;
printf ("%d ", i);
pthread_mutex_lock (&odd_mux);
pthread_cond_signal (&odd);
pthread_mutex_unlock (&odd_mux);
} while (i < 100);
pthread_mutex_unlock (&even_mux);
}
void print_odd ()
{
pthread_mutex_lock (&odd_mux);
pthread_mutex_lock (&main_mux);
pthread_cond_signal (&ready);
pthread_mutex_unlock (&main_mux);
int i = 1;
do {
pthread_cond_wait (&odd, &odd_mux);
i += 2;
printf ("%d ", i);
pthread_mutex_lock (&even_mux);
pthread_cond_signal (&even);
pthread_mutex_unlock (&even_mux);
} while (i < 100);
pthread_mutex_unlock (&odd_mux);
}
int main (void)
{
pthread_t podd, peven;
pthread_mutex_init (&odd_mux, NULL);
pthread_mutex_init (&even_mux, NULL);
pthread_mutex_init (&main_mux, NULL);
printf ("The values are:\n");
pthread_mutex_lock (&main_mux);
if (pthread_create (&podd, NULL, (void *) &print_odd, NULL) != 0) {
exit (1);
}
pthread_cond_wait (&ready, &main_mux);
if (pthread_create (&peven, NULL, (void *) &print_even, NULL) != 0) {
exit (1);
}
pthread_cond_wait (&ready, &main_mux);
pthread_mutex_unlock (&main_mux);
pthread_mutex_lock (&even_mux);
pthread_cond_signal (&even);
pthread_mutex_unlock (&even_mux);
pthread_join (podd, NULL);
pthread_join (peven, NULL);
printf ("\ndone\n");
return 0;
}
您使用条件变量的方式存在缺陷。对你来说,他们本身似乎是一个传达需要做某事的渠道。相反,使用它们作为指标来检查当前状态是否需要做任何事情。
伪代码:
mutex m
condition_var odd
condition_var even
integer i
function handle odd numbers:
lock(m)
while true:
if i is odd:
print i
increment i
signal even
wait odd
function handle even numbers:
lock(m)
while true:
if i is even:
print i
increment i
signal odd
wait even
main:
i = 0
start thread to handle odd numbers
start thread to handle even numbers
如您所见,在等待之前,线程会检查共享计数器是奇数还是偶数,然后相应地执行操作。但是,它不需要事件,特别是在 main() 中启动线程和发出事件信号之间没有竞争条件。
免责声明:条件变量应该这样使用,但绝不是好的MT编程!请务必阅读并理解针对您问题的评论!