gpt4 book ai didi

c - 使用一个信号量实现两个线程的线程同步

转载 作者:行者123 更新时间:2023-11-30 19:38:49 24 4
gpt4 key购买 nike

我想同步线程打印从1到20,奇数由线程1打印,偶数由线程2打印

我用两个信号量实现了这一点。

问题:

1) 仅使用一个信号量可以实现这一目标吗?

2)有没有有效的方法来实现这一目标?

如果可能,请提供示例。

sem_t bin_sem1, bin_sem2;
int count = 1;

int main()
{
int ret;
pthread_t a_thread, b_thread;

ret = sem_init(&bin_sem1, 0, 1);
if (ret != 0)
{
perror("semaphore1 initialization failed\n");
exit(EXIT_FAILURE);
}
ret = sem_init(&bin_sem2, 0, 0);
if (ret != 0)
{
perror("semaphore2 initialization failed\n");
exit(EXIT_FAILURE);
}

ret = pthread_create(&a_thread, NULL, thread_fun1, NULL);
if (ret != 0)
{
perror("Thread1 creation failed");
exit(EXIT_FAILURE);
}

ret = pthread_create(&b_thread, NULL, thread_fun2, NULL);
if (ret != 0)
{
perror("Thread2 creation failed");
exit(EXIT_FAILURE);
}

printf("Waiting for threads to finish\n");
ret = pthread_join(a_thread, NULL);
if (ret != 0)
{
perror("Thread1 join failed");
exit(EXIT_FAILURE);
}
printf("Thread1 joined");

ret = pthread_join(b_thread, NULL);
if (ret != 0)
{
perror("Thread2 join failed");
exit(EXIT_FAILURE);
}
printf("Thread2 joined");

exit(EXIT_SUCCESS);
}

void *thread_fun1(void *arg)
{
int val=0, val2=0;
while (count < 20)
{
sem_wait(&bin_sem1);
sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2);
printf("T 1 : after wait : sem 1 = %d, sem 2 = %d\n", val, val2);

printf("T 1 : count = %d\n", count++);

sem_post(&bin_sem2);
sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2);
printf("T 1 : after post : sem 1 = %d, sem 2 = %d\n", val, val2);
}
pthread_exit(NULL);
}
void *thread_fun2(void *arg)
{
int val=0, val2=0;
while (count < 20)
{
sem_wait(&bin_sem2);
sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2);
printf("\t\t\t\t\t\tT 2 : after wait : sem 1 = %d, sem 2 = %d\n", val, val2);

printf("\t\t\t\t\t\tT 2 : count = %d\n", count++);

sem_post(&bin_sem1);
sem_getvalue(&bin_sem1, &val);sem_getvalue(&bin_sem2, &val2);
printf("\t\t\t\t\t\tT 2 : after post : sem 1 = %d, sem 2 = %d\n", val, val2);
}
pthread_exit(NULL);
}

最佳答案

嗯,可以只使用一个信号量,但是以一种 hacky 的方式。您可以使用它存储实际值,然后在线程 2 中打印偶数,在线程 1 中打印奇数,而不是使用互斥体等信号量。这是一个示例,但不是从 1 到 20 打印,而是从 20 打印到1 但如果需要的话可以很容易地修改。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

void *a_func(void *arg) {
sem_t *mySem = (sem_t *) arg;
int value = 20;

while (value > 0) {
if (value % 2 == 1) {
printf("thread 1 : %d\n", value);
sem_wait(mySem);
}
sem_getvalue(mySem, &value);
}
}

void *b_func(void *arg) {
sem_t *mySem = (sem_t *) arg;
int value = 20;

while (value > 0) {
if (value % 2 == 0) {
printf("thread 2 : %d\n", value);
sem_wait(mySem);
}
sem_getvalue(mySem, &value);
}
}

int main() {
sem_t mySem;
pthread_t a_thread, b_thread;

if (sem_init(&mySem, 0, 20)) {
// handle error
}

if (pthread_create(&a_thread, NULL, a_func, &mySem)) {
// handle error
}

if (pthread_create(&b_thread, NULL, b_func, &mySem)) {
// handle error
}

// wait for threads to finish
pthread_join(a_thread, NULL);
pthread_join(b_thread, NULL);
}

但是,信号量很少以这种方式使用,因此我建议使用原子类型,它更现代并且非常适合您的用例。这是一个简单的例子:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdatomic.h>

void *a_func(void *arg) {
atomic_int *myInt = (atomic_int *) arg;
int value = 20;

while (value > 0) {
if (value % 2 == 1) {
//printf("thread 1 : %d\n", value);
value = atomic_fetch_sub(myInt, 1) + 1;
continue;
}
value = atomic_load(myInt);
}
}

void *b_func(void *arg) {
atomic_int *myInt = (atomic_int *) arg;
int value = 20;

while (value > 0) {
if (value % 2 == 0) {
//printf("thread 2 : %d\n", value);
value = atomic_fetch_sub(myInt, 1) + 1;
continue;
}
value = atomic_load(myInt);
}
}

int main() {
atomic_int myInt = ATOMIC_VAR_INIT(20); // set myInt to 20
pthread_t a_thread, b_thread;

if (pthread_create(&a_thread, NULL, a_func, &myInt)) {
// handle error
}

if (pthread_create(&b_thread, NULL, b_func, &myInt)) {
// handle error
}

// wait for threads to finish
pthread_join(a_thread, NULL);
pthread_join(b_thread, NULL);
}

就性能而言,单个信号量程序和基于原子类型的程序的运行速度比您提供的代码快得多。然而,在这种规模下,您仅使用 1-20 范围内的数字,性能差异可以忽略不计。

关于c - 使用一个信号量实现两个线程的线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37499136/

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