- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个关于 Linux 上的 C 的编程问题。此处显示的代码是我尝试编写代码的大型服务器的“快照”。
为了解释,我想:
我的 Ring Buffer 不工作。我不确定我是否对缓冲区编码不当,或者信号量是否没有像我希望的那样工作。
我包含了 'server.c' 和 'circbuff.c' 还有一个 linkedlist.h 库,但我相信它可以工作
可能的问题?
我全局声明了 buffer_t 缓冲区(环形缓冲区)。我没有 malloc 它。
????
任何愿意提供帮助的人都将不胜感激。
关于如何让线程与链表或环形缓冲区对话的建议是最受欢迎的。
输出总是不同的,但它插入环形缓冲区的总是比弹出的多。
OUTPUT: ..format = 'PUSH: child line# thread'
PUSH: 2264 line 0 thread: 139746191480576
PUSH: 2264 line 0 thread: 139746183087872
PUSH: 2264 line 1 thread: 139746183087872
Buffer underflow
pop 0
Buffer underflow
pop 0
Buffer underflow
pop 0
PUSH: 2275 line 0 thread: 139746191480576
PUSH: 2275 line 0 thread: 139746191480576
更多输出
PUSH: 4208 line 0 thread: 140707316717312
PUSH: 4208 line 1 thread: 140707316717312
PUSH: 4208 line 2 thread: 140707316717312
PUSH: 4208 line 3 thread: 140707316717312
PUSH: 4208 line 4 thread: 140707316717312
PUSH: 4208 line 5 thread: 140707316717312
pop 4208 line 0
pop 4208 line 0
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <semaphore.h>
#include <dirent.h>
#include <sys/wait.h>
#include <errno.h>
#include "circbuff.h"
#include "server.h"
#define SNAME "/OS"
#define MAXDIRPATH 1024
#define MAXKEYWORD 256
#define MAXLINESIZE 1024
#define MAXOUTSIZE 2048
sem_t * sem_wrt;
sem_t * sem_empty;
sem_t * sem_full;
sem_t * sem_mutex;
buffer_t buffer; //a circular buffer pointer array that reads info from a linked list
void * producer(void *arg); //thread producer
void * consumer(void *arg); //thread consumer
int main( int argc, char *argv[]){
if (argc != 3){
printf("Three arguments required .../client <arbitrary> <**buffer_size**>\n");
exit(0);
}
int reqsize= atoi(argv[1]);
int bbuff= atoi(argv[2]);
//buffer_t *buf;
int qbuffsize= reqsize*(MAXDIRPATH+MAXKEYWORD);
//char tok1[MAXDIRPATH];
//char tok2[MAXKEYWORD];
int child_num, status;
/*** Semaphore open */
sem_wrt=sem_open("/sem_wrt", O_CREAT, S_IRUSR | S_IWUSR, 1);
if (sem_wrt == SEM_FAILED) {
perror("server: sem_open failed for semaphone sem_wrt");
return EXIT_FAILURE;
}
sem_empty=sem_open("/sem_empty", O_CREAT, S_IRUSR | S_IWUSR, bbuff); //semaphore waits for bbuff number of things to stop process
if (sem_empty == SEM_FAILED) {
perror("server: sem_open failed for semaphone sem_empty");
return EXIT_FAILURE;
}
sem_full=sem_open("/sem_full", O_CREAT, S_IRUSR | S_IWUSR, 0);
if (sem_full == SEM_FAILED) {
perror("server: sem_open failed for semaphone sem_full");
return EXIT_FAILURE;
}
sem_mutex=sem_open("/sem_mutex", O_CREAT, S_IRUSR | S_IWUSR, 1);
if (sem_mutex == SEM_FAILED) {
perror("server: sem_poen failed for semaphone sem_mutex");
return EXIT_FAILURE;
}
/* Create 4 child processes (each will have 11 threads per below, 1 producer, 10 consumers) */
pid_t pid;
int ct;
for(ct=0; ct<4; ct++){
pid=fork(); //make 5 children
child_num++;
}
if(pid==0){//IF CHILD PROCESS
struct ThreadList* t_list=NULL; //delcare a list of threads
t_list= create_list(); //create the list of thread_info_nodes
init(&buffer, bbuff); //initial circular buffer (declared GLOBALLY), which to multiple threads write, 1 thread reads
pthread_t ctid; //consumer thread id
pthread_create(&ctid, NULL, consumer, t_list); //create one consumer/writer/pop-list thread
/* make n_cnt producer threads (10 threads) that take node->string from a linked list and push to a ring buffer of pointers */
int n_cnt;
for(n_cnt=0; n_cnt<10; n_cnt++){
struct thread_info_node *tnode = malloc(sizeof(struct thread_info_node));//make a node on the heap
init_tnode(tnode, n_cnt, NULL, " line "); //initialize node info ..a string
insert_tail( tnode, t_list); //insert node to tail of list
pthread_create( &(tnode->tid), NULL, producer, t_list); //create a few producer threads that read list
}
//When child process is done, close semaphores to release resources used by child
sem_close(sem_wrt);
sem_close(sem_empty);
sem_close(sem_full);
sem_close(sem_mutex);
}
else{// if the PARENT
/*wait for child processes to finish*/
int cnt;
for(cnt=0; cnt < child_num ; cnt++){
waitpid(-1, &status, 0);}
sem_close(sem_wrt);
sem_close(sem_empty);
sem_close(sem_full); //printf("close sem_full= %d\n", sem_close(sem_full) );
sem_close(sem_mutex);
sem_unlink("/sem_wrt");
sem_unlink("/sem_empty");
sem_unlink("/sem_full"); //printf("unlink sem_full= %d\n", sem_unlink("/sem_full") );
sem_unlink("/sem_mutex");
}
return 0;
}
void * producer(void *arg){
struct ThreadList *list = arg;
struct thread_info_node *tmp = list->head;
pthread_t tid= pthread_self();
char thread_id[MAXLINESIZE];
/* push all but last string from linked list*/
// I AM PUSHING ONLY THE 'node->string' value, not the whole node. IS THIS THE WR0NG WAY TO DO IT???
while(tmp->next != NULL){
sem_wait(sem_empty); //decrement empty. if 0 no more empty, stop process.
sem_wait(sem_mutex);
/*** CRITICAL SECTION ***/
snprintf(thread_id, 10, "%lu", tid);
//strcat(tmp->filename, thread_id);
printf("PUSH: %s thread: %lu\n", tmp->filename, tid);
push( &buffer, tmp->filename );
///--------------------//
sem_post(sem_mutex);
sem_post(sem_full);
tmp= tmp->next;
}
/* push last string left in linked list, and an exit message for the consumer */
sem_wait(sem_empty); //decrement empty. if 0 no more slots empty, stop process.
sem_wait(sem_mutex);
/*** CRITICAL SECTION ***/
snprintf(thread_id, 10, "%lu", tid);
strcat(tmp->filename, thread_id);
printf("PUSH: %s\n", tmp->filename);
push( &buffer, tmp->filename );
printf("SPECIAL_EXIT_CODE\n");
push( &buffer, "SPECIAL_EXIT_CODE");
///--------------------//
sem_post(sem_mutex);
sem_post(sem_full);
return NULL;
}
void * consumer(void *arg){
//struct ThreadList *list = arg;
char outline[MAXOUTSIZE];
while(1){
sem_wait(sem_full);
sem_wait(sem_mutex);
/******* CRITICAL SECTION ******/
//printf("==>CONSUMER THREAD\n");
strcpy(outline, popqueue(&buffer));
printf("pop %s \n", outline );
if (strcmp(outline,"SPECIAL_EXIT_CODE")==0) break;
/********************************/
sem_post(sem_mutex);
sem_post(sem_empty);
}//end WHILE*/
return NULL;
}
#ifndef __CIRCBUFF_h__
#define __CIRCBUFF_h__
#include <stdio.h>
#include <stdlib.h>
#define MAXDIRPATH 1024
#define MAXKEYWORD 256
#define MAXLINESIZE 1024
#define MAXOUTSIZE 2048
struct buffer {
int size;
int start;
//int end; // position of last element
/* Tracking start and end of buffer would waste
* one position. A full buffer would always have
* to leave last position empty or otherwise
* it would look empty. Instead this buffer uses
* count to track if buffer is empty or full
*/
int count; // number of elements in buffer
/* Two ways to make buffer element type opaque
* First is by using typedef for the element
* pointer. Second is by using void pointer.
*/
/* different types of buffer:
int *element; // array of integers
char *element; // array of characters
void *element; // array of void type (could cast to int, char, etc)
char **element; //array of char pointers (array of strings)
void **element; // array of void pointers
Choosing array of void pointers since it's the most flexible */
void **element;
};
typedef struct buffer buffer_t;
void init(buffer_t *buffer, int size) {
buffer->size = size;
buffer->start = 0;
buffer->count = 0;
//buffer->element = malloc(sizeof(buffer->element)*size);
/* allocated array of void pointers. Same as below */
//buffer->element = malloc(sizeof(void *) * size);
/* Allocate array of char poitners*/
buffer->element = malloc(sizeof(char **) * size);
}
int full(buffer_t *buffer) {
if (buffer->count == buffer->size) {
return 1;
} else {
return 0;
}
}
int empty(buffer_t *buffer) {
if (buffer->count == 0) {
return 1;
} else {
return 0;
}
}
void push(buffer_t *buffer, void *data) {
int index;
if (full(buffer)) {
printf("Buffer overflow\n");
} else {
index = buffer->start + buffer->count;
if (index >= buffer->size) {
index = 0;
//index= index - buffer->size;//6
}
buffer->element[index] = data;
buffer->count++;
}
}
void * popqueue(buffer_t *buffer) {
void * element;
if (empty(buffer)) {
printf("Buffer underflow\n");
return "0";
} else {
/* FIFO implementation */
element = buffer->element[buffer->start];
buffer->start++;
buffer->count--;
if (buffer->start == buffer->size) {
buffer->start = 0;
}
return element;
}
}
void * popstack(buffer_t *buffer) {
int index;
if (empty(buffer)) {
printf("Buffer underflow\n");
return "0";
} else {
/* LIFO implementation */
index = buffer->start + buffer->count - 1;
if (index >= buffer->size) {
index = buffer->count - buffer->size - 1;
//index= index-buffer->size
//index = buffer->count – buffer->size – 1;
}
buffer->count--;
return buffer->element[index];
}
}
#endif
最佳答案
问题是 fork() 不共享全局变量。子进程和父进程都有自己的缓冲区副本。为此,您应该使用共享内存。
关于c - 生产者消费者信号量线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43221532/
我将 Bootstrap 与 css 和 java 脚本结合使用。在不影响前端代码的情况下,我真的很难在css中绘制这个背景。在许多问题中,人们将宽度和高度设置为 0%。但是由于我的导航栏,我不能使用
我正在用 c 编写一个程序来读取文件的内容。代码如下: #include void main() { char line[90]; while(scanf("%79[^\
我想使用 javascript 获取矩阵数组的所有对 Angular 线。假设输入输出如下: input = [ [1,2,3], [4,5,6], [7,8,9], ] output =
可以用pdfmake绘制lines,circles和other shapes吗?如果是,是否有documentation或样本?我想用jsPDF替换pdfmake。 最佳答案 是的,有可能。 pdfm
我有一个小svg小部件,其目的是显示角度列表(参见图片)。 现在,角度是线元素,仅具有笔触,没有填充。但是现在我想使用一种“内部填充”颜色和一种“笔触/边框”颜色。我猜想line元素不能解决这个问题,
我正在为带有三角对象的 3D 场景编写一个非常基本的光线转换器,一切都工作正常,直到我决定尝试从场景原点 (0/0/0) 以外的点转换光线。 但是,当我将光线原点更改为 (0/1/0) 时,相交测试突
这个问题已经有答案了: Why do people write "#!/usr/bin/env python" on the first line of a Python script? (22 个回
如何使用大约 50 个星号 * 并使用 for 循环绘制一条水平线?当我尝试这样做时,结果是垂直(而不是水平)列出 50 个星号。 public void drawAstline() { f
这是一个让球以对角线方式下降的 UI,但球保持静止;线程似乎无法正常工作。你能告诉我如何让球移动吗? 请下载一个球并更改目录,以便程序可以找到您的球的分配位置。没有必要下载足球场,但如果您愿意,也可以
我在我的一个项目中使用 Jmeter 和 Ant,当我们生成报告时,它会在报告中显示 URL、#Samples、失败、成功率、平均时间、最短时间、最长时间。 我也想在报告中包含 90% 的时间线。 现
我有一个不寻常的问题,希望有人能帮助我。我想用 Canvas (android) 画一条 Swing 或波浪线,但我不知道该怎么做。它将成为蝌蚪的尾部,所以理想情况下我希望它的形状更像三角形,一端更大
这个问题已经有答案了: Checking Collision of Shapes with JavaFX (1 个回答) 已关闭 8 年前。 我正在使用 JavaFx 8 库。 我的任务很简单:我想检
如何按编号的百分比拆分文件。行数? 假设我想将我的文件分成 3 个部分(60%/20%/20% 部分),我可以手动执行此操作,-_-: $ wc -l brown.txt 57339 brown.tx
我正在努力实现这样的目标: 但这就是我设法做到的。 你能帮我实现预期的结果吗? 更新: 如果我删除 bootstrap.css 依赖项,问题就会消失。我怎样才能让它与 Bootstrap 一起工作?
我目前正在构建一个网站,但遇到了 transform: scale 的问题。我有一个按钮,当用户将鼠标悬停在它上面时,会发生两件事: 背景以对 Angular 线“扫过” 按钮标签颜色改变 按钮稍微变
我需要使用直线和仿射变换绘制大量数据点的图形(缩放图形以适合 View )。 目前,我正在使用 NSBezierPath,但我认为它效率很低(因为点在绘制之前被复制到贝塞尔路径)。通过将我的数据切割成
我正在使用基于 SVM 分类的 HOG 特征检测器。我可以成功提取车牌,但提取的车牌除了车牌号外还有一些不必要的像素/线。我的图像处理流程如下: 在灰度图像上应用 HOG 检测器 裁剪检测到的区域 调
我有以下图片: 我想填充它的轮廓(即我想在这张图片中填充线条)。 我尝试了形态学闭合,但使用大小为 3x3 的矩形内核和 10 迭代并没有填满整个边界。我还尝试了一个 21x21 内核和 1 迭代,但
我必须找到一种算法,可以找到两组数组之间的交集总数,而其中一个数组已排序。 举个例子,我们有这两个数组,我们向相应的数字画直线。 这两个数组为我们提供了总共 7 个交集。 有什么样的算法可以帮助我解决
简单地说 - 我想使用透视投影从近裁剪平面绘制一条射线/线到远裁剪平面。我有我认为是使用各种 OpenGL/图形编程指南中描述的方法通过单击鼠标生成的正确标准化的世界坐标。 我遇到的问题是我的光线似乎
我是一名优秀的程序员,十分优秀!