使用信号量在 C 中同步 3 个线程的分段错误

Segmentation fault usint semaphores to synchronize 3 threads in C

我正在使用信号量同步 c 中的 3 个线程,以便打印像 aabcaabcaabc 这样的序列,但我的代码在 Linux.

中给出了分段错误

我看不出我的代码有什么问题,我制作了 3 个信号量,每个线程一个,并以线程 1 打印 aa 和线程 2 打印 b 的方式同步它们等等。

我该怎么做才能让它发挥作用?

#include<pthread.h>
#include<semaphore.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/shm.h>
sem_t* sem1;
sem_t* sem2;
sem_t* sem3;


void* printA(void* a)
{
    sem_wait(sem2);
    printf("a");
    printf("a");
    sem_post(sem2);
}

void* printB(void* a)
{
    sem_wait(sem2);
    printf("b");
    sem_post(sem3);
}

void* printC(void* a)
{

    sem_wait(sem3);
    printf("c");
    sem_post(sem1);

}

int main()
{

  sem_init(sem1, 0, 1);
  sem_init(sem2, 0, 0);
  sem_init(sem3, 0, 0);

  pthread_t thread1;
  pthread_t thread2;
  pthread_t thread3;

  pthread_create(&thread1, NULL, &printA, NULL);
  pthread_create(&thread2, NULL, &printB, NULL);
  pthread_create(&thread3, NULL, &printC, NULL);

  pthread_join(thread1, NULL);
  pthread_join(thread2, NULL);
  pthread_join(thread3, NULL);

  sem_destroy(sem1);
  sem_destroy(sem2);
  sem_destroy(sem3);
}

运行 您在 debugger 中的代码揭示了段错误的位置。使用 backtrace 第 41 行或 main.c (sem_init(sem1, 0, 1);).

Reading symbols from a.out...done.
(gdb) run
Starting program: /home/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at main.c:41
41        sem_init(sem1, 0, 1);
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
__new_sem_init (sem=0x0, pshared=0, value=1) at sem_init.c:44
44      sem_init.c: No such file or directory.
(gdb) bt
#0  __new_sem_init (sem=0x0, pshared=0, value=1) at sem_init.c:44
#1  0x00000000004008a6 in main () at main.c:41

问题是 sem1 是一个初始化指针。您需要传递一个指向实例化 sem_t 对象的指针。

sem_t sem1;
sem_t sem2;
sem_t sem3;

然后:

  sem_init( &sem1, 0, 1);
  sem_init( &sem2, 0, 0);
  sem_init( &sem3, 0, 0);

并将 sem1 更改为 &sem1 等等,当然还有其他地方。

请注意,虽然这会阻止您的代码出现段错误,但它会挂起,因为没有线程在 sem1 上等待。可能 printA() 应该等待 sem1 而不是 sem2