- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的程序应该使用生产者线程将文件中的行读入缓冲区,该缓冲区一次最多可容纳 numlines,然后使用消费者线程将文件的单词添加到链接列表中,具体取决于如果单词的字符数是奇数或偶数,则将该单词附加到列表中(如果该单词尚不存在),如果该单词已在列表中,则将其添加到计数中。输出将是一个奇数列表和偶数列表,其中包含单词以及它们在文件中出现的频率。我在 Mint Linux 上运行这个
该程序的使用方式类似于 ./exec -b numlines -t maxcounters -d filedelay -D threaddelay file,所以我现在使用 ./exec -b 4 -t 1 -d 0 -D 0 file 。当附加文件的程序时,我看到我的生产者线程正确地放入了文件的 4 行,但消费者的 get 似乎每次都返回不同的输出。我对 pthreads 很陌生,有人可以告诉我我的 get 有什么问题吗?
#define _GNU_SOURCE
#include <features.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
//globals
int numlines;
int maxcounters;
int filedelay;
int threaddelay;
#define MAXSIZE 2048
#define OVER (-1)
char* lastLine;
/* Circular buffer of integers. */
struct prodcons
{
char** data; /* the actual data */
pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */
int readpos, writepos; /* positions for reading and writing */
pthread_cond_t notempty; /* signaled when buffer is not empty */
pthread_cond_t notfull; /* signaled when buffer is not full */
};
//linked lists for odd and even
struct node
{
char *word;
int timesAppeared;
struct node *next;
};
int checkargs(int argc, char* argv[]);
static void init (struct prodcons *b);
static void put (struct prodcons *b, char* line);
static char *get (struct prodcons *b);
static void *producer (void *args);
static void *consumer (void *args);
static void addWord (char *word, struct node **head);
//buffer and lists
struct prodcons buffer;
struct node *odd = NULL;
struct node *even = NULL;
//mutexes for list
pthread_mutex_t oddlock;
pthread_mutex_t evenlock;
int main(int argc, char* argv[]){
if (checkargs(argc, argv) == 1){
printf("CORRECT ARGS!\n");
}
else{
exit(1);
}
int filecount;
filecount = argc - 9;
pthread_t th_a, th_b;
void *retval;
init(&buffer);
//create threads
if(pthread_create (&th_a, NULL, producer, argv) != 0){
fprintf(stderr, "Error: producer create problem\n");
exit(1);
}
if(pthread_create (&th_b, NULL, consumer, argv) != 0){
fprintf(stderr, "Error: consumer create problem\n");
exit(1);
}
/* Wait until producer and consumer finish. */
if(pthread_join(th_a, &retval) != 0){
fprintf(stderr, "ERROR: producer join problem\n");
exit(1);
}
printf("hey121342343\n");
if(pthread_join(th_b, &retval) != 0){
fprintf(stderr, "ERROR: consumer join problem\n");
exit(1);
}
printf("hey123\n");
struct node *ptr;
printf("\nODD LIST BEGIN\n");
printf("%s %s\n", "Word", "# appeared");
for( ptr = odd; ptr != NULL; ptr = ptr->next){
printf("%s %d\n", ptr->word, ptr->timesAppeared);
}
printf("\nEVEN LIST BEGIN\n");
printf("%s %s\n", "Word", "# appeared");
for( ptr = even; ptr != NULL; ptr = ptr->next){
printf("%s %d\n", ptr->word, ptr->timesAppeared);
}
return 0;
}
static void addWord (char* word, struct node **head){
struct node *headnode;
struct node *addnode;
struct node *lastnode;
//check for word
for(headnode = *head; headnode != NULL; headnode = headnode->next){
if(strcmp(headnode->word, word) == 0){
//same
printf("SAME WORD!\n");
headnode -> timesAppeared++;
return;
}
}
//not in list? make a new node
addnode = (struct node *) malloc(sizeof(struct node));
addnode -> word = malloc(strlen(word) + 1);
strcpy(addnode->word, word);
printf("the word %s has been added!\n", addnode->word);
addnode-> timesAppeared = 1;
addnode->next = NULL;
//insert into linked list
headnode = *head;
lastnode = NULL;
//possible debug, try taking out the strcmp condition
//(strcmp(addnode->word, headnode->word) > 0)
//traverse to end
while(( headnode != NULL)){
lastnode = headnode;
headnode = headnode->next;
}
addnode->next = headnode;
//in case of empty list
if(lastnode == NULL){
*head = addnode;
}
else{
lastnode ->next = addnode;
}
return;
}
/* Initialize a buffer */
static void init (struct prodcons *b)
{
//make a buffer of correct size and check
b->data = malloc(sizeof(char *) * numlines);
if (b->data == NULL){
perror("failed buffer malloc");
exit(1);
}
pthread_mutex_init (&b->lock, NULL);
pthread_cond_init (&b->notempty, NULL);
pthread_cond_init (&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/* Store an integer in the buffer */
static void put (struct prodcons *b, char* line)
{
pthread_mutex_lock (&b->lock);
/* Wait until buffer is not full */
while ((b->writepos + 1) % numlines == b->readpos)
{
pthread_cond_wait (&b->notfull, &b->lock);
/* pthread_cond_wait reacquired b->lock before returning */
}
/* Write the data and advance write pointer */
printf("THIS IS THE READLINE in PUT %s\n", line);
b->data[b->writepos] = line;
printf("AFTER PUT command: %s is at WRITEPOS %d\n", b->data[b->writepos], b->writepos);
b->writepos++;
if (b->writepos >= numlines){
b->writepos = 0;
}
/* Signal that the buffer is now not empty */
pthread_cond_signal (&b->notempty);
pthread_mutex_unlock (&b->lock);
}
/* Read and remove an integer from the buffer */
static char* get (struct prodcons *b)
{
char* line;
pthread_mutex_lock (&b->lock);
/* Wait until buffer is not empty */
while (b->writepos == b->readpos)
{
pthread_cond_wait (&b->notempty, &b->lock);
}
/* Read the data and advance read pointer */
printf("THIS IS THE LINE in GET%s\n", b->data[b->readpos]);
line = b->data[b->readpos];
printf("AFTER GET command: %s is at READPOS %d\n", b->data[b->readpos], b->readpos);
b->readpos++;
if (b->readpos >= numlines){
b->readpos = 0;
}
/* Signal that the buffer is now not full */
pthread_cond_signal (&b->notfull);
pthread_mutex_unlock (&b->lock);
return line;
}
/* A test program: one thread inserts integers from 1 to 10000,
the other reads them and prints them. */
static void *producer (void *args)
{
FILE *file;
char readline[MAXSIZE];
char **argv = args;
int filePos = 9;
//go through every file
while (argv[filePos] != NULL){
printf("This is the file opened: %s", argv[filePos]);
file = fopen(argv[filePos], "r");
//read file lines
while(fgets(readline, MAXSIZE, file) == readline){
printf("THIS IS THE READLINE in PRODUCER%s", readline);
put(&buffer, readline);
}
// lastLine = &readline;
// printf("THIS IS THE LAST READLINE: %s\n", lastLine);
fclose(file);
filePos+= 1;
}//endwhile
// need a way for the consumer to know when the thread has finished
put(&buffer, "endofile");
// int a;
// for(a = 0; a < ccount; a++){
// put(NULL);
// }
printf("-------------PRODUCER FINISHED FILLING BUFFER-------------\n");
return NULL;
}
static void *consumer (void *args)
{
char name[2] = "a";
char *removedLine;
char* token;
//get line
removedLine = get(&buffer);
while(removedLine != "endofile"){
printf("This is the removedline: %s", removedLine);
token = strtok_r(removedLine, " ", &removedLine);
printf("This is the TOKEN %s and its length: %zu\n", token, strlen(token));
//process each word
while(token != NULL){
//odd
if( (strlen(token) - 1) % 2 == 1){
pthread_mutex_lock(&oddlock);
printf("adding the word in odd !\n");
addWord(token, &odd);
pthread_mutex_unlock(&oddlock);
}
//even
if( (strlen(token) - 1) % 2 == 0){
pthread_mutex_lock(&evenlock);
printf("adding the word in even!\n");
addWord(token, &even);
pthread_mutex_unlock(&evenlock);
}
//subsequent call, has to make the first arg null from the man page
token = strtok_r(NULL, " ", &removedLine);
}//inner while
// printf("This is thread A!\n");
removedLine = get(&buffer);
printf("This is the next line, after the while: %s", removedLine);
}//outer while
printf("-------------CONSUMER FINISHED FILLING BUFFER-------------\n");
return;
}
// //need to make 2 lists for odd and even
// struct linkedlist{
// struct node *start;
// struct node *end;
// };
// struct list odd;
// struct list even;
int checkargs(int argc, char* argv[]){
//have checkers to see if the program went through all the args properly
int checknumlines;
int checkmaxcounters;
int checkfiledelay;
int checkthreaddelay;
printf("ARGC %d\n", argc);
//10 args or more (depending on files)
if(argc <= 9){
fprintf(stderr, "Error: Please enter correct number of args. \n");
return 0;
}
//grab data
int i;
for(i = 0; i < (argc - 1); i++){
//travel through until -b, get that info of the next
if(strcmp(argv[i], "-b") == 0){
numlines = atoi(argv[i+1]);
if (numlines <= 0){
fprintf(stderr, "Error: numlines is not a positive non-zero integer. \n");
return 0;
}
checknumlines = -1;
}
//travel through until -t, get that info of the next
if(strcmp(argv[i], "-t") == 0){
maxcounters = atoi(argv[i +1]);
if((maxcounters <= 0) || (maxcounters > 26)){
fprintf(stderr, "Error: maxcounters needs to be a positive non-zero integer less than or equal to 26. \n");
return 0;
}
checkmaxcounters = -1;
}
//travel through until -d, get that info of the next
if(strcmp(argv[i], "-d") == 0){
filedelay = atoi(argv[i+1]);
if(filedelay < 0 ){
fprintf(stderr, "Error: filedelay needs to be a positive integer. \n");
return 0;
}
checkfiledelay = -1;
}
//travel through until -D, get that info of the next
if(strcmp(argv[i], "-D") == 0){
threaddelay = atoi(argv[i+1]);
if(threaddelay < 0 ){
fprintf(stderr, "Error: threaddelay needs to be a positive integer. \n");
return 0;
}
checkthreaddelay = -1;
}
}
printf("CHECKS: This is numlines: %d, This is maxcounters: %d, This is filedelay: %d, This is threaddelay: %d \n", checknumlines, checkmaxcounters, checkfiledelay, checkthreaddelay);
if(checknumlines != -1 || checkmaxcounters != -1|| checkfiledelay != -1|| checkthreaddelay!= -1){
fprintf(stderr, "Error: incorrect args.\n");
return 0;
}
printf("This is numlines: %d, This is maxcounters: %d, This is filedelay: %d, This is threaddelay: %d \n", numlines, maxcounters, filedelay, threaddelay);
return 1;
}
我用来检查的文件:
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
aaaaaaaaaaa
aaaaaaaaaaaa
aaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaa
运行 3 次后的输出(减去调试语句)1.
ODD LIST BEGIN
Word # appeared
aaaaa
3
aaaaaaaaa
1
aaaaaaaaaaa
1
a
1
aaaaaaaaaaaaa
2
aaaaaaaaaaaaaaa
1
aaaaaaaaaaaaaaaaa
4
EVEN LIST BEGIN
Word # appeared
aaaaa
1
2
aaaaaa
1
aaaaaaaaaaaa
2
aaaaaaaaaaaaaaaa
1
2.
ODD LIST BEGIN
Word # appeared
aaaaa
4
aaaaaaaaa
3
aaaaaaaaaaaaaaa
1
aaaaaaaaaaaaaaaaa
4
EVEN LIST BEGIN
Word # appeared
3
aaaaaaaa
1
aaaaaaaaaaaa
1
aaaaaaaaaaaaaa
2
aaaaaaaaaaaaaaaa
1
3.
ODD LIST BEGIN
Word # appeared
aaaaa
2
aaaaaaa
1
aaaaaaaaa
1
aaaaaaaaaaa
1
aaaaaaaaaaaaa
1
aaaaaaaaaaaaaaa
1
aaaaaaaaaaaaaaaaa
4
EVEN LIST BEGIN
Word # appeared
2
aaaaaa
1
aaaaaaaa
1
aaaaaaaaaa
1
aaaaaaaaaaaa
1
aaaaaaaaaaaaaa
1
aaaaaaaaaaaaaaaa
2
感谢您的宝贵时间!我尝试尽可能地进行描述,如果这不好的话请告诉我(stackoverflow 的新手)
最佳答案
向缓冲区添加行的方式不正确:
static void *producer (void *args)
{
char readline[MAXSIZE];
// ...
while(fgets(readline, MAXSIZE, file) == readline){
printf("THIS IS THE READLINE in PRODUCER%s", readline);
put(&buffer, readline);
}
// ...
}
请注意,您正在将行读入本地变量 readline
中,并将 readline
添加到缓冲区中。然后循环并用下一行覆盖 readline 的内容。因此,之前添加到缓冲区的内容将被覆盖。您需要做的是复制每一行。例如,如果您有一个 strdup()
函数:
while(fgets(readline, MAXSIZE, file) == readline){
printf("THIS IS THE READLINE in PRODUCER%s", readline);
put(&buffer, strdup(readline));
}
现在添加到缓冲区的每个字符串都是一个已分配的副本。您需要记住在使用后释放该副本。
关于c - Posix 线程消费者无法正确打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29610490/
有没有更好的方法用 PHP 将数据输出到 html 页面? 如果我想在 php 中用一些 var 制作一个 div,我会写类似的东西 print (''.$var.''); 或 echo "''.$v
我可以使用 java awt print 来打印文档/文件而不是使用 javax print 吗?我发现在 java awt print 中有一个选项可以使用 AttributedString 将内容
目前我通过以下方式运行 R 脚本: R --slave argument1 argument2 ... 我想知道 R 中关于如何退出脚本并发出警告的最佳实践,q() 会这样做吗? if(!file.
谁能告诉我如何编写一个程序,用 gcc 编译时打印 c ,用 g++ 编译时打印 c++? 最佳答案 #ifdef __cplusplus printf("c++\n"); #else
我需要支持在 KitKat 设备上打印,但我的目标 SDK 是 13(无法更改)。 特别是我需要打印一个 webview。 这是用于打印 webview 的 API: http://developer
我正在尝试创建一个简单的函数,其中 python 将根据您的年份输入计算年龄。我已经尝试了几种方法,但我没有运气 atm。 附:对不起,我是新手。 ame = input(" Enter your n
JavaFX 2.0 是否支持打印?我有一个文本区域,我从中获取文本然后我想打印它,但似乎没有这个功能。 当然,这里我说的是打印到打印机。 :) 最佳答案 尚不支持。作为一种解决方法,您可以使用 Ja
我试图找出printOn的重点。我查看了一些实现它的类,看起来它只是帮助打印不同数据类型的单位。这是准确的吗? 如果是这样,有人能指出我如何为我自己的类(class)实现这一点的正确方向吗?我将在可能
我无法让 IE 打印我的 Canvas (使用 excanvas 生成)...我使用的是最新版本的 excanvas。 http://dl.dropbox.com/u/997831/canvas.ht
我搜索了很多但没有人回答我的问题,我读到在这样的信号处理程序中使用 cout 是不安全的: void ctrlZHandler(int sig_num) { //SIGTSTP-18
我有兴趣打印一系列查询。我有以下代码。 start = datetime.datetime(2012, 2, 2, 6, 35, 6, 764) end = datetime.datetime(201
public class javaClass { public static void main(String [] arg) { String row1 = "A____A"
我需要写入前一行的命令,例如不带\n 的 print()。 下面是一些示例代码: a=0 print("Random string value") if a==0: print_to_prev
我有一个使用 UIKit 和 Objective C 的旧 iOS 应用程序,我目前正在将其移植到 SwiftUI 和 Swift。一切都很顺利,我喜欢 Swift 和 SwiftUI。该应用程序已经
我创建了一个求和函数,它接受一个开始编号和一个结束编号,并返回这两点之间的总和答案 def print_sum_equations(start_number,end_number):
在 Perl 6 中,print 和有什么区别? , put和 say ? 我怎么看 print 5不同,但 put 5和 say 5看起来一样。 最佳答案 put $a就像 print $a.Str
我正在使用 here 中的 getOrgChart 库,我正在尝试打印整个图表,而不仅仅是可见部分。不幸的是,当使用标准库打印功能时,它只会打印出第一部分,而我不知道如何打印整个图表(该图表相当宽,大
我制作了一个非常适合 A4 页面的 View 。现在我想打印它。请注意,我没有使用drawRect或类似的东西,只是一个带有 subview 和文本标签的普通 View 。我的问题是,我对该 View
由于 Cocoa-Java 已弃用,我正在将 Cocoa-Java 代码迁移到 Cocoa + JNI。该代码打印存储在文件中的图像。新的 Cocoa 代码基本上是: NSImage *image =
这个问题已经有答案了: Printing a TDBGrid (4 个回答) 已关闭 6 年前。 如何在不安装或下载组件的情况下打印 DBGrid? 或者 如何将 DBGrid 的数据放入 RichE
我是一名优秀的程序员,十分优秀!