c - 多线程消息同步

标签 c multithreading pthread-join

我需要在 C 中的每个线程中打印 2 条消息,每条消息并同步它们。

第一个线程打印一个,第二个线程打印两个。

所以我的代码是这样的

void printOne(void* empty){
    while(1) printf("One ");  
}

void printTwo(void* empty){
    while(1) printf("Two\n");
}


int main(){

    pthread_t t_1,t_2;

    pthread_create(&t_1, NULL,(void *)&printOne,NULL);
    pthread_create(&t_2, NULL,(void *)&printTwo,NULL);

    pthread_join(t_1,NULL);
    pthread_join(t_2,NULL);

    exit(0);
}

问题在于随机打印一和二但并不总是按该顺序打印。我想让它总是打印两个接一个。我对 join 命令有点困惑。

提前致谢!

最佳答案

您混淆了关于 synchronization 的一些基本概念这里。 pthread_join() 函数将以您所想的方式保证同步。 join 用于在线程执行完成后 同步线程,即在您的线程中调用return 之后。这样,调用线程将等待指定线程完成其执行,这正是您的代码正在做的事情。主线程正在等待:

  1. 首先,t_1 结束
  2. 然后,t_2 结束

如果 t_2 在 t_1 之前结束,主线程仍然会被 t_1 阻塞,因为必须遵守这个顺序。当然,它们都不会在您的代码中完成执行,因为它们都陷入了无限循环 (while(1))。

您尝试实现的目标可以使用多种技术来完成。我建议你使用 semaphores (如果你想使用 POSIX API )或 mutex (已在 pthread 库中实现)。

这是一个示例,说明如何更改代码以获得同步:

void printOne(void* empty){
    while(1)
    { 
      sem_wait(&s1); //wait for semaphore s1
      printf("One ");  
      sem_post(&s2); //signal semaphore s2
    }
}

void printTwo(void* empty){
    while(1)
    {
      sem_wait(&s2); //wait for semaphore s2
      printf("Two\n");
      sem_post(&s1); //signal semaphore s1
    }
}

sem_t s1, s2; //Declare the semaphores globally, so the threads can access them

int main(){

    pthread_t t_1,t_2;

    sem_init(&s1, 0, 1); //Initialize s1 with 1
    sem_init(&s2, 0, 0); //Initialize s2 with 0

    pthread_create(&t_1, NULL,(void *)&printOne,NULL);
    pthread_create(&t_2, NULL,(void *)&printTwo,NULL);

    pthread_join(t_1,NULL);
    pthread_join(t_2,NULL);

    exit(0);
}

这样,您的代码可以保证一条消息接一条消息打印到您的输出中:

一个
两个
一个
两个
...

关于c - 多线程消息同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19498917/

相关文章:

c - 多维数组越界访问

c - C : Addition and Printing简介

c - 运行程序时出现段错误和变化的输出

c++ - Pthreads,与 pthread_join(pthread_t, void**) 混淆

linux - 线程 : pthread_cond_signal() not giving control to another thread on waiting condition

c - 使用 open mp 的慢速稀疏矩阵 vector 积 (CSR)

c - 在 gdb 中找不到已知的行号

c# - Task.Delay() 和 new Task(()=>Thread.Sleep()) 的区别

java - 了解 Java 多线程中的内存可见性

c - PTHREAD_CANCELED 和线程的启动函数返回值有什么问题