我正在使用c实现信号量的多线程生产者 - 消费者计划。每个缓冲区结构都有两个通用信号量 - 一个用于空缓冲区,另一个用于完整缓冲区。但是,当程序进入readInput函数时,这两个信号量的值将更改为随机值。线程结构中的信号量很好,但是线程结构中IO联合内的缓冲区结构中的信号量由于某种原因而改变。知道为什么会这样吗?
#include "st.h"
#include "semaphore.h"
#include "buffer.h"
/*Definitions here*/
//Input location.
#define DEFAULT_IN stdin
//Output location.
#define DEFAULT_OUT stdout
//Line width
#define LINE_SIZE 80
#define SLEEP_TIME 333333
//Shorthand for structure components
#define INPUT thread->in
#define MUTEX thread->mutex
#define OUTPUT thread->out
/*Global variables here*/
//The input/output can be a stream or a buffer.
typedef union
{
buffer *bufferIO; //Buffer to read from/write to.
FILE *stream; //An I/O stream.
} IO;
//Each thread has an input, a semaphore, and an output.
typedef struct
{
IO in; //Either an input stream or a buffer to read.
semaphore *mutex; //Pointer to a binary semaphore.
IO out; //Either an output stream or a buffer to write.
} Thread;
/*Function prototypes here*/
void *readInput(void *s);
void *processLines(void *s);
void *processAsterisks(void *s);
void *writeOutput(void *s);
int main (int argc, char const *argv[]) //The main function
{
st_init();
/*Binary semaphore*/
semaphore mutex; //Binary semaphore for mutual exclusion.
createSem(&mutex, 1);
printf("Beginning...\n");
/*The three buffers between threads*/
buffer B1, B2, B3;
createBuf(&B1);
createBuf(&B2);
createBuf(&B3);
/*The 5 data locations*/
IO input, buffer1, buffer2, buffer3, output; //stdin, 3 buffers, stdout
/*Set the unions*/
input.stream = DEFAULT_IN; //Input stream
buffer1.bufferIO = &B1; //Contains raw input
buffer2.bufferIO = &B2; //Newlines have become spaces
buffer3.bufferIO = &B3; //** has become ^
output.stream = DEFAULT_OUT; //Output stream, 80 at a time
/*Initialize the threads*/
Thread input_thread = {input, &mutex, buffer1}; //Recieve input
Thread proc1_thread = {buffer1, &mutex, buffer2}; //Returns to spaces
Thread proc2_thread = {buffer2, &mutex, buffer3}; //** to ^
Thread output_thread = {buffer3, &mutex, output}; //Output 80 characters and a newline.
printf("%i\n", input_thread.out.bufferIO->emptyBuffers->value);
/*Create the actual threads*/
if(st_thread_create(readInput, &input_thread, 0, 0) == NULL)
{
perror("st_thread_create for input thread failure");
exit(1);
}
printf("%i\n", input_thread.out.bufferIO->emptyBuffers->value);
if(st_thread_create(processLines, &proc1_thread, 0, 0) == NULL)
{
perror("st_thread_create for line thread failure");
exit(1);
}
if(st_thread_create(processAsterisks, &proc2_thread, 0, 0) == NULL)
{
perror("st_thread_create for asterisk thread failure");
exit(1);
}
if(st_thread_create(writeOutput, &output_thread, 0, 0) == NULL)
{
perror("st_thread_create for output thread failure");
exit(1);
}
st_thread_exit(NULL);
return 0;
}
/*Function definitions here*/
void *readInput(void *s)
{
Thread *thread = s;
char c; //An individual character.
printf("Type some input.\n");
do
{
down(MUTEX);
c = getc(INPUT.stream); //Consume a character from input.
printf("%i\n", OUTPUT.bufferIO->emptyBuffers->value);
deposit(OUTPUT.bufferIO, c); //Produce a character.
up(MUTEX);
st_usleep(SLEEP_TIME); //Wait.
}
while(c != EOF); //Do-while in order to pass on the EOF as an exit flag.
//EOF reached - exit thread.
//assert(c == EOF);
printf("\nDone reading.");
st_thread_exit(NULL);
}...
用gdb查看后,我发现了这个:
Hardware watchpoint 10: (*(*input_thread.out.bufferIO).emptyBuffers).value
(gdb) c
Continuing.
Hardware watchpoint 10: (*(*input_thread.out.bufferIO).emptyBuffers).value
Old value = 80
New value = 4216725
0x000000395221467c in _dl_runtime_resolve () from /lib64/ld-linux-x86-64.so.2
不确定_dl_runtime_resolve是什么。
答案 0 :(得分:0)
信号量和缓冲区在主线程中创建为堆栈变量,因此当主线程退出指向信号量的地址时,缓冲区无效且行为不可预测。进行适当的设计并为变量提供适当的范围,暂时使所有变量成为全局变量。在上面的代码中将以下内容作为全局
信号量互斥; //用于互斥的二进制信号量。
和
IO输入,buffer1,buffer2,buffer3,输出; // stdin,3个缓冲区,stdout
重新编译并执行